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.
git clone --depth 1 https://github.com/Scopeo/draftnrunWrote 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.
[](https://agentmods.dev/rules/scopeo/draftnrun/mcp)<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>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.
| Model | Per session | Once 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 |
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.
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/orengine/. - Tools are thin wrappers: validate inputs, call
DraftnrunClientorSupabaseClient, format response. No business logic. - Tool naming:
snake_caseverbs matching the API action (list_,get_,create_,update_,delete_). - Auth:
SupabaseProviderfrom 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 toSITE_URL + authorization_pathfor consent. - Use
get_access_token()fromfastmcp.server.dependenciesto get the JWT;.tokenfor 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) userequire_role.trigger_cronis org-scoped (member+). - Workflow creation:
create_workflowcreates workflow-type projects. Agent projects usecreate_agent. - Target-org permissions: tools that accept an explicit
org_idmust 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:
MCPIntegrationis auto-configured. Usesentry_sdk.loggerfor structured logging. - Response trimming: large payloads (>50KB) are truncated by
DraftnrunClient._trim_response. Trimming is controllable per-tool viaToolSpec.trim(defaultTrue) and per-call via thetrimparameter on all HTTP methods.get_graphandlist_componentsare untrimmed. - When adding/removing/renaming MCP tools: update
mcp_server/README.md, the relevantdocs://resource inmcp_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 inmcp_server/docs.pyin the same diff. - Example UUIDs in
docs.pymust come from code (uuid.uuid4()), stored as module constants / placeholders replaced at import — never hand-written hex in prose. See_GRAPH_DOC_*indocs.py. - When changing file/document behavior: always update
docs://file-managementandmcp_server/README.mdin the same diff. - When adding a new tool domain: create a file in
mcp_server/tools/, register inmcp_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_keywithout org/role scope, and missing roles on role-scoped specs. - Body fields with
Nonevalues are omitted from the JSON payload (not serialized as JSONnull). - Redis fallback is recoverable: after a connection failure, the client retries automatically after 60 s.
- Treat
_truncatedresponses as partial data, never as complete truth. get_org_token_usagereports monthly input/output tokens from stored trace spans only;years/monthsaccept lists or"all", and per-model rows depend on persistedmodel_idvalues, 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 computedtool_description.tool_description_overridecustomizes the description shown to the AI. When changing tool port behavior, updatedocs://graphs,docs://agent-config, andmcp_server/README.md. - QA custom columns: entry
custom_columnsdicts are keyed by column UUID, not display name. Always uselist_custom_columnsto discover the mapping before writing. Seedocs://qaanddocs://known-quirks. - CSV tools:
export_dataset_csv/import_dataset_csvhandle dataset round-trips. The export builds CSV from paginatedlist_entriesinternally (nograph_runner_idneeded). 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_organizationrace and fail. Seedocs://known-quirks. update_graphandupdate_graph_topology_v2tool descriptions warn callers toget_guide('graphs')first and to close the browser tab to avoid race conditions with the UI auto-save.update_graph_topology_v2additionally documents full-replace edge semantics.configure_agent,add_tool_to_agent, andremove_tool_from_agentare for AGENT-type projects only. For WORKFLOW-type projects, useupdate_component_parametersto change component parameters, orget_graph+update_graphfor structural changes.- Keep
get_project_overviewparity with API-level project settings exposed byget_project. - AI Agent
skip_tools_with_missing_oauth(defaultTrue): at agent startup, tools withis_available()False (e.g. missing OAuth) are excluded from the LLM tool registry. Documented indocs://agent-config,docs://integrations, andmcp_server/README.mdguardrails; change viaconfigure_agentorupdate_component_parameters. - Neverdrop-branded Google integration components use distinct OAuth provider filters:
google-mail-neverdropandgoogle-calendar-neverdrop. Always discover the component viasearch_components()and verify matching OAuth connections withlist_oauth_connections(provider_config_key)before graph edits. update_component_parametersperforms 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 overupdate_graphfor single-parameter changes on workflow components. Avoid modifyingdrives_output_schemafields (payload_schema,output_format) unless intending to change dynamic output ports. Internally filters out INPUT-kind parameters and converts read-formatfield_expressionsto write-formatinput_port_instancesbefore PUT to prevent lossy round-trips (e.g.json_buildexpressions whosevalueis the non-invertible placeholder[JSON_BUILD]). RaisesToolErrorif the caller tries to set a literal value on a parameter wired with a non-literal field expression (reforjson_build); useupdate_component_v2to rewire those parameters.- Run retries are run-scoped via
retry_run(project_id, run_id, env=None). The backend reuses the original run'sgraph_runner_idand persistedrun_inputs. The optionalenvis a legacy fallback only needed when bothgraph_runner_idandenvare null on the original run; do not reintroduce project-scoped retry policy fields. update_graphsupports optional optimistic locking: passlast_edited_timefrom 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 ininput_port_instancessupportfile_key(e.g.{"type": "ref", "file_key": "start", "port": "output"}) as an alternative toinstanceUUID; the v2 mapper resolvesfile_key→ UUID before saving.update_component_v2uses full-replace semantics forparametersandinput_port_instances— callers must include ALL parameters from the graph, not only the ones being changed. For single-parameter changes preferupdate_component_parameters. - Edge
origin/destinationaccept 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 viaparse_expression_flexible. - If/Else branch edges use
order: 0for true andorder: 1for false/else. Setenable_false_path=trueon the component before wiringorder: 1; when it is false, false conditions select no downstream branch.
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.
- 2d ago First seen · 55 lines · 0 tokens per session scan A 86761952296b
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.
Other cursor rules, from other repositories
python
Python best practices and patterns for modern software development with Flask and SQLite.
api-property-optionality-hygiene
Fix ApiProperty/ApiPropertyOptional optionality mismatches in DTO files; use for scheduled batch fixes or DTO edits.
django
Definitive guidelines for writing maintainable, performant, and secure Django applications, emphasizing modern best practices, clear code organization, and efficient patterns.
cursor
You are working on the checkout service. Preserve transaction integrity and auditability.
shared-libraries
Shared libraries - condition framework, inventory containers, file-backed DB, itinerary, references.
env-validation-gate
Env validation gate — every app with ≥1 required env var validates its contract at boot via Zod; raw process.env is banned outside the env module. Full pattern in .claude/skills/t2000-env-gate/.