{
  "name": "one",
  "title": "ONE MCP Server",
  "version": "1.1.0",
  "description": "ONE remote OAuth MCP server for Codex, including authoritative GeoTech brand standards and a local stdio fallback for approved developer workflows.",
  "transport": {
    "type": "streamable-http",
    "url": "https://one.geotech.one/api/mcp",
    "command": "node",
    "args": [
      "C:\\Projects\\GeoCRM\\mcp\\geocrm-mcp.mjs"
    ]
  },
  "alternateTransports": [
    {
      "type": "streamable-http",
      "url": "https://geotech-crm.web.app/api/mcp",
      "description": "Permanent Firebase Hosting fallback"
    },
    {
      "type": "stdio",
      "command": "node",
      "args": [
        "C:\\Projects\\GeoCRM\\mcp\\geocrm-mcp.mjs"
      ]
    }
  ],
  "authentication": {
    "modes": [
      {
        "name": "oauth",
        "description": "Recommended for the ONE Codex plugin. Each person signs in with Google and receives only their live board viewer/editor grants.",
        "resourceMetadata": "https://one.geotech.one/.well-known/oauth-protected-resource"
      },
      {
        "name": "api",
        "description": "Use a permanent ONE API key generated by a ONE admin. Requires the Firebase Function behind /api/** to be deployed.",
        "environment": {
          "GEOCRM_AUTH_MODE": "api",
          "GEOCRM_MCP_PROFILE": "tasks",
          "GEOCRM_API_BASE_URL": "https://one.geotech.one/api",
          "GEOCRM_API_KEY": "<GEOCRM_API_KEY>"
        }
      },
      {
        "name": "firebase",
        "description": "Use a short-lived Firebase ID token copied from ONE.",
        "environment": {
          "GEOCRM_AUTH_MODE": "firebase",
          "GEOCRM_FIREBASE_ID_TOKEN": "<FIREBASE_ID_TOKEN>"
        }
      }
    ]
  },
  "tools": [
    {
      "name": "geocrm_health",
      "description": "Check the ONE connector and configured credentials."
    },
    {
      "name": "get_app_info",
      "description": "Return canonical ONE app URLs, API/docs links, and short answer hints for questions like what is the ONE website, web page, login URL, API URL, or docs page."
    },
    {
      "name": "get_brand_standards",
      "description": "Return authoritative GeoTech logos, exact colour values, typography, patterns, hosted assets, the four-page digital design system, and all 89 Brand, Color, Scale, and Typography variables. Call before presentations, Complex Decisions, websites, documents, charts, diagrams, product design, or other visual work."
    },
    {
      "name": "list_logs",
      "description": "Read the last seven days of ONE diagnostic logs with filters for app errors, LLM messages, connector traffic, and system errors."
    },
    {
      "name": "write_log",
      "description": "Write a short-lived diagnostic log entry for an app, LLM, connector, or system event. API mode requires write access."
    },
    {
      "name": "list_boards",
      "description": "List ONE boards, optionally filtered by board name."
    },
    {
      "name": "get_board",
      "description": "Get board metadata, columns, groups, and item count."
    },
    {
      "name": "upload_complex_decision",
      "description": "Create or replace a rich HTML Complex Decision. The server always makes it private to the signed-in ONE owner, sanitizes active content, and clears old report grants."
    },
    {
      "name": "delete_board",
      "description": "Remove one non-protected ONE board from the active workspace and archive a recoverable copy. Requires write access."
    },
    {
      "name": "list_board_items",
      "description": "List items on one board, optionally filtered by text across visible fields."
    },
    {
      "name": "search_items",
      "description": "Search ONE items across all boards by default, or within one explicit board, using flexible token and prefix matching."
    },
    {
      "name": "find_board_item_duplicates",
      "description": "Find duplicate candidate groups on one board by exact or similar normalized item names."
    },
    {
      "name": "find_contact_duplicates",
      "description": "Find duplicate candidate groups on the Contacts board by shared email, shared phone, exact name, or similar name."
    },
    {
      "name": "upsert_contact",
      "description": "Create or update a Contacts record by email/name and link it to an existing or newly created Companies record. Requires write access."
    },
    {
      "name": "get_item",
      "description": "Get one item from ONE with visible fields, updates, assets, and subitems."
    },
    {
      "name": "get_brain_dump_context",
      "description": "Read the Brain Dump board schema and recent ideas before generating new concepts. Available in full and brain_dump profiles."
    },
    {
      "name": "add_brain_dump_ideas",
      "description": "Populate the Brain Dump board with a batch of ideas generated directly in Codex. Available in full and brain_dump profiles."
    },
    {
      "name": "ensure_board_column",
      "description": "Return an existing board column or create it when it does not exist. Requires write access."
    },
    {
      "name": "create_item",
      "description": "Create an item on any ONE board using existing column IDs or titles. Requires write access."
    },
    {
      "name": "update_item",
      "description": "Update an item name and/or field values. Requires write access."
    },
    {
      "name": "move_board_items",
      "description": "Move matching items on one board to another group with optional field filters and dry-run safety. Requires write access."
    },
    {
      "name": "delete_item",
      "description": "Soft-delete a ONE item and write an audit update. Requires write access."
    },
    {
      "name": "set_item_file_field",
      "description": "Set a file or image field on an item in ONE and create the field if needed. Requires write access."
    },
    {
      "name": "add_item_update",
      "description": "Add an update note to one item in ONE. Requires write access."
    },
    {
      "name": "merge_board_item_duplicates",
      "description": "Merge duplicate items on one board into a primary item while preserving candidate field values. Requires write access."
    },
    {
      "name": "merge_contact_duplicates",
      "description": "Merge duplicate Contacts items into a primary contact while preserving secondary emails and candidate field values. Requires write access."
    },
    {
      "name": "list_signature_requests",
      "description": "List e-signature agreements and their routing, delivery, and completion status. Requires documents:read."
    },
    {
      "name": "get_signature_request",
      "description": "Get one agreement with documents, recipients, fields, delivery options, and history. Requires documents:read."
    },
    {
      "name": "list_signature_templates",
      "description": "List reusable agreement templates with documents, roles, fields, messages, and options. Requires documents:read."
    },
    {
      "name": "list_hardware_inventory",
      "description": "List Hardware assets, custody, status, costs, procurement links, and document counts. The remote OAuth MCP requires the signed-in user's current Hardware BackOffice grant."
    },
    {
      "name": "get_hardware_asset",
      "description": "Get one Hardware asset with custody history, movements, procurement metadata, and safe document metadata. The remote OAuth MCP requires the signed-in user's current Hardware BackOffice grant."
    },
    {
      "name": "list_procurement_requests",
      "description": "List Procurement requests visible to the signed-in requester, approver, watcher, owner, or admin. The remote OAuth MCP requires the signed-in user's current Procurement BackOffice grant."
    },
    {
      "name": "get_procurement_request",
      "description": "Get one visible Procurement request with its approval chain, comments, lifecycle, and safe attachment metadata. The remote OAuth MCP requires the signed-in user's current Procurement BackOffice grant."
    },
    {
      "name": "create_signature_request",
      "description": "Create a draft agreement from up to 10 local PDF/image files with recipients, routing, message, reminders, and expiration. Requires documents:write."
    },
    {
      "name": "create_signature_request_from_template",
      "description": "Create a draft from a reusable template by filling its recipient roles. Requires documents:write."
    },
    {
      "name": "prepare_signature_request",
      "description": "Place signature, initials, text, identity, date, title, and checkbox fields on a draft. Requires documents:write."
    },
    {
      "name": "save_signature_template",
      "description": "Save a prepared draft as a reusable agreement template. Requires documents:write."
    },
    {
      "name": "send_signature_request",
      "description": "Send a prepared agreement using parallel or sequential routing. Requires documents:send."
    },
    {
      "name": "void_signature_request",
      "description": "Void a live agreement and invalidate all private signing links. Requires documents:send."
    },
    {
      "name": "get_task_context",
      "description": "Resolve a ONE task URL and return all task fields, comments, attachment metadata, image-only metadata, and a concurrency revision."
    },
    {
      "name": "get_task_image",
      "description": "Fetch one authenticated parent-task or subtask image and return it as MCP visual content."
    },
    {
      "name": "add_task_comment",
      "description": "Add one concise, idempotent Codex-attributed comment to a nested project task."
    },
    {
      "name": "set_task_review_state",
      "description": "Set a task to In Progress or Review. Codex cannot mark tasks Done."
    },
    {
      "name": "create_backup",
      "description": "Queue a protected compact or full ONE backup and wait for the background Firebase job to return verified backup metadata."
    },
    {
      "name": "get_backup_job",
      "description": "Read the queued, running, completed, or failed state of a backup job created by the same backups-scoped API key."
    },
    {
      "name": "finance_get_categorization_context",
      "description": "Retrieve bounded targets, taxonomy IDs, deterministic history votes, and similar human-approved decisions; every UI Exclude from AI row is removed before model context."
    },
    {
      "name": "finance_get_overview",
      "description": "Read the Finance overview with account, transaction, import, category, currency, reconciliation, and review summaries. The remote OAuth MCP requires the signed-in user's current Finance BackOffice grant."
    },
    {
      "name": "finance_list_accounts",
      "description": "Read Finance account definitions, calculated summaries, and recent valuations. The remote OAuth MCP requires the signed-in user's current Finance BackOffice grant."
    },
    {
      "name": "finance_list_transactions",
      "description": "Read a bounded Finance transaction view with filters, decisions, evidence counts, and Fin Results matches. The remote OAuth MCP requires the signed-in user's current Finance BackOffice grant."
    },
    {
      "name": "finance_list_imports",
      "description": "Read the Finance import registry with source names, parsers, accounts, row outcomes, warnings, and dates while omitting source hashes. The remote OAuth MCP requires the signed-in user's current Finance BackOffice grant."
    },
    {
      "name": "finance_list_invoices",
      "description": "List Accounts Receivable invoice drafts and issued or paid invoices. The remote OAuth MCP requires the signed-in user's current Finance BackOffice grant."
    },
    {
      "name": "finance_get_invoice",
      "description": "Read one complete Accounts Receivable invoice with its audit history and payment-match candidates."
    },
    {
      "name": "finance_create_invoice",
      "description": "Create an editable Accounts Receivable customer-invoice draft. Remote OAuth requires Finance BackOffice edit access."
    },
    {
      "name": "finance_import_invoice",
      "description": "Local stdio tool: upload a local PDF/image, extract it with Gemini, and create a review-required Accounts Receivable draft. Duplicate source files reuse the existing draft."
    },
    {
      "name": "finance_start_categorization_run",
      "description": "Start an idempotent, audited categorization run using GPT-5.6 Sol, GPT-5.6 Terra, or OpenRouter Kimi K3."
    },
    {
      "name": "finance_submit_ai_decisions",
      "description": "Submit structured votes for validation and save eligible category votes with AI provenance unless the run is dry-run."
    },
    {
      "name": "finance_review_ai_decision",
      "description": "Mark an AI decision correct/incorrect; excluding removes that transaction's vector records and re-including queues a fresh eligible replacement."
    },
    {
      "name": "finance_get_vector_memory_stats",
      "description": "Read the active Finance embedding namespace, model, dimensions, vector count, and latest operation."
    },
    {
      "name": "finance_clear_vector_memory",
      "description": "Clear generated Finance embeddings and vector links with exact confirmation while preserving all source Finance records."
    },
    {
      "name": "finance_sync_vector_memory",
      "description": "Create or reuse embeddings for selected human-approved decisions or a bounded YYYY-MM page; with finance:apply, replace one transaction's prior vector records using replaceExisting=true."
    },
    {
      "name": "finance_get_cash_forecast",
      "description": "Read the deterministic 13-week or 12-month cash outlook, balances, scenarios, category drivers, recurring patterns, plans, FX provenance, and quality warnings."
    },
    {
      "name": "finance_create_cash_plan",
      "description": "Create one retry-safe planned cash inflow, outflow, or security-linked investment purchase with recurrence and scenario certainty."
    },
    {
      "name": "finance_update_cash_plan",
      "description": "Update or restore a planned cash event using optimistic concurrency."
    },
    {
      "name": "finance_archive_cash_plan",
      "description": "Reversibly archive a planned cash event so it no longer affects the forecast."
    },
    {
      "name": "finance_update_cash_forecast_settings",
      "description": "Update the global minimum-cash threshold and default cash scope and horizon."
    },
    {
      "name": "finance_record_investment_portfolio",
      "description": "Record a reconciled dated investment-account snapshot with executed positions, cost basis, available cash, disclosed purchase costs, annual ING/fund cost rates, and estimated sale costs. Only available cash enters Flow."
    },
    {
      "name": "upload_account_balance_screenshot",
      "description": "Upload a local direct ING account, ING credit-card, or Wise screenshot for Gemini recognition, deterministic known-account matching, and automatic dated balance updates without storing the raw image. ING investment Belegd/Gelddeel values are retained as invested and available-cash components; credit cards use Current balance only, including zero."
    }
  ],
  "localStdioToolsDescription": "These project-task, personal-focus, and Slack task-automation tools are available only through the local stdio server with GEOCRM_MCP_PROFILE=tasks; they are not exposed by the remote OAuth transport.",
  "localStdioTools": [
    {
      "name": "list_project_tasks",
      "description": "List project tasks or find tasks linked to an exact Slack thread URL."
    },
    {
      "name": "get_my_work",
      "description": "Return the personal key owner's per-project focus tasks, permitted open assignments, and visible team focus."
    },
    {
      "name": "get_my_focus",
      "description": "Return the personal key owner's validated current task for every focused project."
    },
    {
      "name": "set_my_focus",
      "description": "Set one assigned, non-Done task as current for its project while preserving focus in other projects."
    },
    {
      "name": "clear_my_focus",
      "description": "Clear one project's current focus, or all focus records when no project is supplied."
    },
    {
      "name": "create_project_tasks",
      "description": "Create one or more Backlog tasks with inferred fields, Slack sources, and one-level subtasks."
    },
    {
      "name": "update_project_task",
      "description": "Safely update a project task while appending context and preserving human-edited fields."
    },
    {
      "name": "get_slack_channel_project",
      "description": "Get the ONE project associated with a Slack workspace and channel."
    },
    {
      "name": "set_slack_channel_project",
      "description": "Associate a Slack workspace and channel with a ONE project."
    },
    {
      "name": "list_slack_task_proposals",
      "description": "List versioned, summary-only Slack task proposals."
    },
    {
      "name": "create_slack_task_proposal",
      "description": "Persist a task preview without storing the raw Slack transcript."
    },
    {
      "name": "refresh_slack_task_proposal",
      "description": "Refresh a pending preview after a thread reply or requested revision, or supersede it when its target was deleted."
    },
    {
      "name": "approve_slack_task_proposal",
      "description": "Apply one exact preview version after participant and thread-snapshot validation."
    }
  ],
  "resources": {
    "humanDocs": "https://one.geotech.one/docs/api",
    "openapi": "https://one.geotech.one/openapi/geocrm.json",
    "agentIndex": "https://one.geotech.one/llms.txt"
  },
  "usagePolicy": {
    "branding": [
      "Call get_brand_standards before producing or substantially revising presentations, Complex Decisions, product or website design, interfaces, documents, reports, charts, diagrams, campaigns, email, social posts, or other visual GeoTech work.",
      "Treat the returned standard as authoritative: start from approved artwork or templates, use exact colour and typography values, preserve clear space and contrast, and never redraw, recolour, crop, stretch, distort, rotate, or rebuild the GeoTech mark.",
      "For decks, social posts, websites, one-pagers, product UI, and internal documents, follow the returned designSystem foundations, workflow, visual language, and guardrails before inventing a new treatment.",
      "Use only the ONE/Firebase-hosted asset URLs returned by get_brand_standards; never substitute external file links for brand assets.",
      "Review the finished work at its actual delivery size before sharing or publishing it."
    ],
    "documents": [
      "Create a Documents / e-signature API key and use the full MCP profile.",
      "Create or select the agreement, add recipients and actions, configure routing/message/reminders/expiration, place fields, then send only after reviewing the returned draft.",
      "Local document paths are read only by the local MCP process; document bytes are stored privately and signing links are never returned by internal list tools."
    ],
    "financeCategorization": [
      "Create a Finance categorization only API key and run the full MCP profile with GPT-5.6 Sol, GPT-5.6 Terra, or OpenRouter Kimi K3.",
      "Start a run, classify only from the supplied compact context and taxonomy IDs, and submit structured votes without chain-of-thought.",
      "Every per-transaction UI exclusion, full bank records, and unrelated ONE records must never be supplied to the model.",
      "A human Manual Decision always wins. Unreviewed AI decisions never become retrieval examples; human-confirmed decisions do."
    ],
    "financeForecast": [
      "Use finance_get_cash_forecast before discussing runway, low-cash dates, or category drivers; quote its as-of date, reporting currency, scope, scenario, and data-quality warnings.",
      "Cash plans are separate from booked transactions. Use a stable idempotency key when creating one and the latest updatedAt value when updating or archiving it.",
      "Forecast numbers are deterministic historical medians and quartiles plus recurring and planned events; never describe them as AI predictions or guaranteed outcomes."
    ],
    "financeAccountScreenshots": [
      "Use the full MCP profile with a finance:write or write-capable API key.",
      "Pass a direct ING account, ING credit-card, or Wise image to upload_account_balance_screenshot; optional as_of_date overrides a date visible in the screenshot or today's UTC date.",
      "Gemini extracts visible balances, but account matching and writes remain deterministic. ING investment Belegd/Gelddeel values are stored together as invested and available-cash components, and only available cash enters the cash forecast. For credit cards, only Current balance is accepted (including zero); available credit, limits, and statement values are rejected, and displayed debt is normalized as negative. Aggregate, ordinary zero, low-confidence, and ambiguous rows are skipped, and the raw screenshot is never stored."
    ],
    "financeInvestmentPortfolios": [
      "Use finance_record_investment_portfolio only with values reconciled to broker evidence: positions plus other items equal invested value, and invested value plus available cash equals the total account balance.",
      "Label purchase and sale costs as disclosed, estimated, or not supplied. Never present an estimated sale cost as a broker quote.",
      "Flow includes only available brokerage cash. Purchase costs already reflected in the current cash/cost basis are not deducted twice; fund costs reduce NAV; optional estimated ING service costs may be forecast as cash spending."
    ],
    "brainDump": [
      "Create a Brain Dump-only API key and set GEOCRM_MCP_PROFILE=brain_dump for a board-scoped Codex connection.",
      "Call get_brain_dump_context before ideating, generate original results in Codex, then call add_brain_dump_ideas to populate the board.",
      "Never place the API key in prompts, board fields, logs, or source control."
    ],
    "developerTasks": [
      "Use GEOCRM_MCP_PROFILE=tasks with a Developer tasks only API key for local Codex development.",
      "Work on a task only when a human assigns it to the virtual Codex assignee and shares the task link with you; assignment is manual pickup, there is no worker queue.",
      "Call get_task_context first and get_task_image for every image before changing code.",
      "Reload task context before each feedback iteration and pass the current revision to writes.",
      "Add one concise result and verification comment, set Review, and leave Done to a human reviewer.",
      "Use GEOCRM_MCP_PROFILE=tasks with a self-service personal agent key for local Codex development."
    ],
    "logs": [
      "Use GET /api/logs or the list_logs MCP tool to inspect recent app, LLM, connector, and system diagnostics before guessing at failures.",
      "Log history is retained for seven days and can be filtered by level, category, connector, source, time range, and text query.",
      "Do not write secrets, live tokens, private keys, session cookies, or credential-bearing snippets to diagnostic logs."
    ],
    "slackBot": [
      "Slack users interact with the ONE app by DMing the app or mentioning it in natural language.",
      "Thread-to-task automation is natural language: ask ONE to turn the current conversation into project tasks or refresh tasks already linked to the thread.",
      "Preview task changes first, refresh the preview after human replies, and publish only the latest version after a thread participant reacts with white_check_mark.",
      "Persist summaries, operations, participant IDs, hashes, and Slack permalinks only; do not persist raw Slack transcripts or attachment bytes.",
      "Slack agents should resolve intent from chat and call ONE API or MCP tools internally for add, delete, edit, remove, search, and update requests.",
      "For bridge execution, prefer npm run bridge on the remote bridge host so the Codex bridge supervises the Slack bot, reuses the Codex chat bridge token, exposes status/log controls, and restarts the bot when it exits while enabled."
    ]
  },
  "security": {
    "notes": [
      "Do not place live API keys in public docs, source control, issue trackers, or agent thread records.",
      "Store GEOCRM_API_KEY in a local client config, password manager, or secret store.",
      "Revoke and rotate keys from the ONE admin drawer when access should change."
    ]
  }
}
