mcp

mcp is a cursor rule for Cursor from Scopeo/draftnrun. It costs 0 tokens per session (2,124 once invoked), scanned A, original, Apache-2.0.

A set of rules for building an MCP server. MCP, or Model Context Protocol, lets AI tools call defined server functions; these rules cover tool names, authentication, permissions, sessions, and organization context.

In plain words
What is it for?
Use it when implementing MCP tools that list, retrieve, create, update, or delete resources, including tools that use Supabase authentication and Redis-backed session context.
Why use it?
It prevents each server tool from handling security and API access differently. The rules separate thin request wrappers from business logic and require checks for identity, roles, and active organizations.

Cursor rule for Cursor

Written for Cursor: installed under .cursor/.

Good fit Use it when implementing MCP tools that list, retrieve, create, update, or delete resources, including tools that use Supabase authentication and Redis-backed session context.

Compare 6 cursor rules from other repositories ↓
Install with agentmods
npx agentmods add rules/scopeo/draftnrun/mcp
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Clone the repo
git clone --depth 1 https://github.com/Scopeo/draftnrun

Made for: Cursor.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for mcp

README.md
[![agentmods](https://agentmods.dev/badge/rules/scopeo/draftnrun/mcp.svg)](https://agentmods.dev/rules/scopeo/draftnrun/mcp)
Your own site
<a href="https://agentmods.dev/rules/scopeo/draftnrun/mcp"><img src="https://agentmods.dev/badge/rules/scopeo/draftnrun/mcp.svg" alt="Measured on agentmods" height="20"></a>
Per session 0 Nothing until a file matches its globs; then the whole rule loads.
When invoked 2,124 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00000 $0.02124
Opus 5 $0.00000 $0.01062
Sonnet 5 $0.00000 $0.00425
Haiku 4.5 $0.00000 $0.00212

Measured 2d ago against content hash 86761952296b, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-07, from the pricing page.

Security

Grade A, and why

mcp scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.cursor/rules/mcp.mdc · 55 lines

How it starts

The opening of the file, as written. The whole thing — 55 lines — stays where its author put it; the contents beside it link to each section on GitHub.

MCP Server Conventions

  • Standalone process — no imports from ada_backend/ or engine/.
  • Tools are thin wrappers: validate inputs, call DraftnrunClient or SupabaseClient, format response. No business logic.
  • Tool naming: snake_case verbs matching the API action (list_, get_, create_, update_, delete_).
  • Auth: SupabaseProvider from FastMCP. Tokens are standard Supabase JWTs. MCP server does NOT issue its own tokens.
  • Consent page: lives in back-office/src/pages/oauth/callback.vue, NOT in the MCP server. Supabase redirects to SITE_URL + authorization_path for consent.
  • Use get_access_token() from fastmcp.server.dependencies to get the JWT; .token for the raw string, .claims["sub"] for user ID.
  • Org context: session-scoped via Redis and keyed by the MCP session ID when available. Tools must check for active org before calling org-scoped endpoints (use require_org_context). Developer+ operations (create/update/delete/pause/resume cron, OAuth, create_agent, knowledge mutations, Typeform webhook setup, git sync configure/disconnect) use require_role. trigger_cron is org-scoped (member+).
  • Workflow creation: create_workflow creates workflow-type projects. Agent projects use create_agent.
  • Target-org permissions: tools that accept an explicit org_id must validate the caller's role on that target organization, not only on the active org session.
  • Component search: search_components(query) must reject blank or whitespace-only queries instead of returning the full catalog.
  • Error handling: never bare except. Map HTTP errors to descriptive MCP tool error messages via ToolError.
  • Sentry: MCPIntegration is auto-configured. Use sentry_sdk.logger for structured logging.
  • Response trimming: large payloads (>50KB) are truncated by DraftnrunClient._trim_response. Trimming is controllable per-tool via ToolSpec.trim (default True) and per-call via the trim parameter on all HTTP methods. get_graph and list_components are untrimmed.
  • When adding/removing/renaming MCP tools: update mcp_server/README.md, the relevant docs:// resource in mcp_server/docs.py, and this rule file in the same diff.
  • When changing any MCP behavior, payload, auth, limitation, or guardrail: update the matching docs:// resource in mcp_server/docs.py in the same diff.
  • Example UUIDs in docs.py must come from code (uuid.uuid4()), stored as module constants / placeholders replaced at import — never hand-written hex in prose. See _GRAPH_DOC_* in docs.py.
  • When changing file/document behavior: always update docs://file-management and mcp_server/README.md in the same diff.
  • When adding a new tool domain: create a file in mcp_server/tools/, register in mcp_server/tools/__init__.py.
  • Never reuse IDs, instance UUIDs, source IDs, or graph JSON from another project/org as a shortcut. Re-fetch current state with get_graph, list_components, search_components, list_sources, etc.
  • Ask for explicit user permission before publish/delete/revoke OAuth or guiding OAuth setup in the web UI.
  • Prefer dedicated components over python_code_runner / terminal_command_runner; keep code tools for small, bounded tasks.
  • Prefer dedicated search components for web research when the catalog already provides them.
  • Do not describe knowledge documents as original downloadable files or claim MCP has a generic file upload/download API unless that behavior actually exists.
  • Factory spec validation at registration time catches unresolved path placeholders, body_org_key without org/role scope, and missing roles on role-scoped specs.
  • Body fields with None values are omitted from the JSON payload (not serialized as JSON null).
  • Redis fallback is recoverable: after a connection failure, the client retries automatically after 60 s.
  • Treat _truncated responses as partial data, never as complete truth.
  • get_org_token_usage reports monthly input/output tokens from stored trace spans only; years/months accept lists or "all", and per-model rows depend on persisted model_id values, not recomputation from prompts or provider APIs.
  • Tool port configurations: component instances in graph payloads include port_configurations (setup modes: ai_filled, user_set, deactivated) and a computed tool_description. tool_description_override customizes the description shown to the AI. When changing tool port behavior, update docs://graphs, docs://agent-config, and mcp_server/README.md.
  • QA custom columns: entry custom_columns dicts are keyed by column UUID, not display name. Always use list_custom_columns to discover the mapping before writing. See docs://qa and docs://known-quirks.
  • CSV tools: export_dataset_csv / import_dataset_csv handle dataset round-trips. The export builds CSV from paginated list_entries internally (no graph_runner_id needed). The import uses multipart file upload to the backend's CSV import endpoint.
  • Client methods: api.get_raw() returns raw text (for non-JSON endpoints). api.post_file() handles multipart uploads. Both are available for custom tools that need non-JSON request/response patterns.
  • Org selection must be sequential — parallel calls with select_organization race and fail. See docs://known-quirks.
  • update_graph and update_graph_topology_v2 tool descriptions warn callers to get_guide('graphs') first and to close the browser tab to avoid race conditions with the UI auto-save. update_graph_topology_v2 additionally documents full-replace edge semantics.
  • configure_agent, add_tool_to_agent, and remove_tool_from_agent are for AGENT-type projects only. For WORKFLOW-type projects, use update_component_parameters to change component parameters, or get_graph + update_graph for structural changes.
  • Keep get_project_overview parity with API-level project settings exposed by get_project.
  • AI Agent skip_tools_with_missing_oauth (default True): at agent startup, tools with is_available() False (e.g. missing OAuth) are excluded from the LLM tool registry. Documented in docs://agent-config, docs://integrations, and mcp_server/README.md guardrails; change via configure_agent or update_component_parameters.
  • Neverdrop-branded Google integration components use distinct OAuth provider filters: google-mail-neverdrop and google-calendar-neverdrop. Always discover the component via search_components() and verify matching OAuth connections with list_oauth_connections(provider_config_key) before graph edits.
  • update_component_parameters performs a read-modify-write on a single component's parameters. It GETs the full graph to locate the component, then PUTs only the target component via the V2 single-component endpoint (/v2/.../components/{instance_id}), avoiding the V1 full-graph hash-based skip. Preferred over update_graph for single-parameter changes on workflow components. Avoid modifying drives_output_schema fields (payload_schema, output_format) unless intending to change dynamic output ports. Internally filters out INPUT-kind parameters and converts read-format field_expressions to write-format input_port_instances before PUT to prevent lossy round-trips (e.g. json_build expressions whose value is the non-invertible placeholder [JSON_BUILD]). Raises ToolError if the caller tries to set a literal value on a parameter wired with a non-literal field expression (ref or json_build); use update_component_v2 to rewire those parameters.
  • Run retries are run-scoped via retry_run(project_id, run_id, env=None). The backend reuses the original run's graph_runner_id and persisted run_inputs. The optional env is a legacy fallback only needed when both graph_runner_id and env are null on the original run; do not reintroduce project-scoped retry policy fields.
  • update_graph supports optional optimistic locking: pass last_edited_time from a previous response to detect concurrent edits (409 Conflict).
  • File-based graph v2 tools: granular tools (create_component_v2, update_component_v2, delete_component_v2, update_graph_topology_v2) for front/MCP. Git sync uses the same service functions internally (no MCP tool). Granular flow: create component → update topology to connect it. Field expression refs in input_port_instances support file_key (e.g. {"type": "ref", "file_key": "start", "port": "output"}) as an alternative to instance UUID; the v2 mapper resolves file_key → UUID before saving. update_component_v2 uses full-replace semantics for parameters and input_port_instances — callers must include ALL parameters from the graph, not only the ones being changed. For single-parameter changes prefer update_component_parameters.
  • Edge origin/destination accept both plain UUID strings and dicts like {"instance_id": "uuid"} — the backend normalizes.
  • JSON-typed parameters (e.g. If/Else conditions) accept both native lists and JSON-encoded strings — the backend normalizes lists via parse_expression_flexible.
  • If/Else branch edges use order: 0 for true and order: 1 for false/else. Set enable_false_path=true on the component before wiring order: 1; when it is false, false conditions select no downstream branch.

Read the full file on GitHub · 55 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 55 lines · 0 tokens per session scan A 86761952296b

Subscribe to this mod's changes

mcp is a cursor rule published in the GitHub repository Scopeo/draftnrun (30 stars, last pushed 4d ago), licensed Apache-2.0. It costs nothing until one of its globs matches a file; then it loads 2,124 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-04.