# FieldMCP > MCP infrastructure platform for agricultural APIs. Integrate with John Deere, Climate FieldView, and more through a unified, LLM-ready interface. The full public content of FieldMCP in one file. A machine-readable link index lives at https://www.fieldmcp.com/llms.txt # Documentation ## Introduction URL: https://www.fieldmcp.com/docs export const metadata = { title: 'Introduction', description: 'FieldMCP — unified MCP infrastructure for agricultural APIs', alternates: { canonical: '/docs' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('Introduction')}&description=${encodeURIComponent('FieldMCP — unified MCP infrastructure for agricultural APIs')}` } } # FieldMCP FieldMCP is an MCP (Model Context Protocol) infrastructure platform for agricultural APIs. Integrate once, access John Deere — and soon Climate FieldView and CNHi — through unified MCP servers. ## What is MCP? The [Model Context Protocol](https://modelcontextprotocol.io) is an open standard that lets AI assistants (like Claude) call external tools and access data sources. FieldMCP implements MCP servers that expose agricultural data as tools any MCP client can use. ## What FieldMCP Provides - **Unified API** — One integration covers multiple agricultural data providers. No need to learn each provider's API separately. - **MCP Native** — Works with any MCP client (Claude Desktop, Claude Code, custom apps). Your AI assistant can directly query field data, equipment status, and agronomic intelligence. - **Normalized Data** — Responses are normalized across providers. A field from John Deere looks the same as a field from any other provider. - **Farm Intelligence** — Built-in agronomic analysis engine with 140+ diagnostic rules. Get yield analysis, soil recommendations, and prioritized action plans. - **Weather Data** — Historical and forecast weather data for any location, including GDD calculations. ## Architecture ```mermaid flowchart TB A("Your App — Claude, custom MCP client") B("FieldMCP Gateway") C("John Deere API") D("Weather API") E("Farm Intelligence Engine") A -- MCP Protocol --> B B -- OAuth --> C B -- REST --> D B -- Direct --> E style B fill:#2d7a4a,stroke:#1f5c36,color:#fff ``` Your application connects to the FieldMCP gateway using the MCP protocol. The gateway is a standard OAuth 2.1 Authorization Server — MCP clients discover it via `/.well-known` endpoints and authenticate using OAuth with PKCE. The gateway handles authentication, rate limiting, data normalization, and provider-specific API calls. ## Available Tools FieldMCP exposes 11 tools across 3 providers: | Provider | Tools | Description | |----------|-------|-------------| | **John Deere** | 4 tools | List resources, field overviews, equipment status, operation search | | **Farm Intelligence** | 6 tools | Field diagnosis, yield analysis, field comparison, action plans, rule lookup | | **Weather** | 1 tool | Historical and forecast weather with GDD, precipitation, temperature | See the [Tools Reference](/docs/tools) for complete documentation. ## Getting Started Head to the [Quickstart](/docs/quickstart) guide to get your first MCP call working. ## Quickstart URL: https://www.fieldmcp.com/docs/quickstart export const metadata = { title: 'Quickstart', description: 'Get your first MCP call working in 3 minutes', alternates: { canonical: '/docs/quickstart' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('Quickstart')}&description=${encodeURIComponent('Get your first MCP call working in 3 minutes')}` } } # Quickstart Get your first MCP call working in 3 minutes. > **Before you start:** You'll need an MCP-compatible client (Claude Desktop, Cursor, Windsurf, or any custom MCP client) and a John Deere developer account at [dev.deere.com](https://developer.deere.com). FieldMCP does not currently provide a sandbox — you'll connect to your real Deere developer org. ## 1. Request Access Request access at the [FieldMCP Dashboard](https://www.fieldmcp.com/signup). Once approved, you'll get a 14-day free trial with 17,000 requests per month per connected organization. ## 2. Connect Your MCP Client Point your MCP client at the FieldMCP gateway. It handles OAuth discovery and client registration automatically — no manual setup required. ## 3. Make Your First Call Ask your AI assistant to list the farmer's organizations: ``` List my John Deere organizations ``` This calls `deere_list_resources` and returns the farmer's John Deere data: ```json { "error": false, "data": { "organizations": [ { "id": "org-12345", "name": "Chen Family Farms", "type": "customer" } ], "farms": [], "fields": [], "totalCounts": { "organizations": 1, "farms": 4, "fields": 12, "equipment": 8 } }, "dataQuality": "COMPLETE" } ``` That's it. Your MCP client now has access to the farmer's John Deere data through FieldMCP's 11 tools. ## Try This Next Ask your assistant to run a field diagnosis: ``` Diagnose my North 40 corn field for the 2026 crop year ``` This calls `intel_diagnose_field` with the farmer's yield history, soil data, and operations. You'll get back prioritized actions with evidence-backed recommendations from 140+ agronomic diagnostic rules. --- ## Next Steps - [OAuth 2.1](/docs/authentication/oauth) — Full OAuth flow reference for custom integrations - [Tools Reference](/docs/tools) — All 11 available tools with schemas and examples - [Rate Limits](/docs/rate-limits) — Per-org quotas and HTTP 429 handling - [Error Handling](/docs/errors) — Every error code and how to recover ## OAuth 2.1 URL: https://www.fieldmcp.com/docs/authentication/oauth export const metadata = { title: 'OAuth 2.1', description: 'Authenticate MCP clients and connect farmers via standard OAuth 2.1', alternates: { canonical: '/docs/authentication/oauth' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('OAuth 2.1')}&description=${encodeURIComponent('Authenticate MCP clients and connect farmers via standard OAuth 2.1')}` } } # OAuth 2.1 FieldMCP is a standard OAuth 2.1 Authorization Server. MCP clients (Claude Desktop, Cursor, custom apps) authenticate using the standard OAuth 2.1 flow with PKCE — no proprietary integration needed. When an MCP client connects, FieldMCP handles everything: the farmer logs into John Deere, selects which organizations to share, and the MCP client receives tokens to make API calls. ## How It Works 1. MCP client discovers FieldMCP via `/.well-known/oauth-authorization-server` 2. MCP client redirects to `/authorize` with PKCE challenge 3. Farmer logs into John Deere and selects organizations 4. FieldMCP issues the MCP client a signed JWT access token + refresh token 5. MCP client uses the JWT to call `/mcp` ```mermaid sequenceDiagram participant Client as MCP Client participant FMCP as FieldMCP participant JD as John Deere Client->>FMCP: GET /authorize FMCP->>JD: redirect to JD login Note over JD: farmer logs in JD->>FMCP: callback with code FMCP->>Client: auth code + redirect Client->>FMCP: POST /token FMCP->>Client: JWT + refresh token Client->>FMCP: POST /mcp (Bearer JWT) FMCP->>JD: JD API calls JD->>FMCP: data FMCP->>Client: tool results ``` ## Discovery MCP clients discover FieldMCP's OAuth endpoints automatically: ```bash # Authorization Server metadata (RFC 8414) curl https://api.fieldmcp.com/.well-known/oauth-authorization-server # Protected Resource metadata (RFC 9728) curl https://api.fieldmcp.com/.well-known/oauth-protected-resource/mcp # Public signing keys (JWKS) curl https://api.fieldmcp.com/.well-known/jwks.json ``` The AS metadata includes a `registration_endpoint` for [Dynamic Client Registration (RFC 7591)](https://datatracker.ietf.org/doc/html/rfc7591). MCP clients like Claude Desktop use this to self-register automatically — no manual app creation needed. ## Authorization Request Redirect the user to `/authorize` with these parameters: | Parameter | Required | Description | |-----------|----------|-------------| | `client_id` | Yes | Obtained via Dynamic Client Registration, or your enterprise app's UUID | | `redirect_uri` | Yes | Must exactly match a registered redirect URI | | `code_challenge` | Yes | PKCE S256 challenge | | `state` | Recommended | Opaque value for CSRF protection | | `scope` | Optional | Space-separated scopes (defaults to `ag1 ag2 ag3 offline_access`) | | `resource` | Optional | RFC 8707 resource indicator | ``` https://api.fieldmcp.com/authorize? client_id=YOUR_APP_ID& redirect_uri=https://yourapp.com/callback& code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM& state=abc123 ``` ## Token Exchange Exchange the authorization code for tokens: ```bash curl -X POST https://api.fieldmcp.com/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code&\ code=AUTH_CODE&\ code_verifier=YOUR_PKCE_VERIFIER&\ client_id=YOUR_APP_ID&\ redirect_uri=https://yourapp.com/callback" ``` Response: ```json { "access_token": "eyJ...", "token_type": "bearer", "expires_in": 3600, "refresh_token": "opaque-refresh-token", "scope": "ag1 ag2 ag3 offline_access" } ``` ## Token Refresh Access tokens expire after 1 hour. Use the refresh token to get new ones: ```bash curl -X POST https://api.fieldmcp.com/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=refresh_token&\ refresh_token=YOUR_REFRESH_TOKEN&\ client_id=YOUR_APP_ID" ``` Refresh tokens are rotated on each use (the old token has a 30-second grace period for retries). Refresh tokens expire after 90 days. ## Token Revocation Revoke a refresh token when disconnecting: ```bash curl -X POST https://api.fieldmcp.com/revoke \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "token=YOUR_REFRESH_TOKEN&token_type_hint=refresh_token" ``` Access tokens (JWTs) cannot be revoked — they expire naturally after 1 hour. ## Using the Access Token Pass the JWT in the `Authorization` header when calling the MCP endpoint: ``` POST /mcp Authorization: Bearer eyJ... Content-Type: application/json ``` The JWT contains the developer ID, farmer ID, and scopes. No `X-Farmer-Id` header is needed — the farmer is identified by the OAuth flow. ## Connecting a Farmer Farmers connect their John Deere accounts through the OAuth flow above. When using Claude Desktop or another MCP client, the connection happens automatically on first use — the farmer logs into John Deere and authorizes access. You can also manage connections in the [Dashboard](/dashboard/connections). ## Scopes | Scope | Access | |-------|--------| | `ag1` | Fields, boundaries, farms, clients | | `ag2` | Equipment, telemetry, operations | | `ag3` | Agronomic data, prescriptions | | `offline_access` | Refresh token for long-lived access | ## Errors | Error | Cause | Resolution | |-------|-------|------------| | `invalid_client` | Unknown `client_id` | Check your app ID in the Dashboard | | `invalid_redirect_uri` | `redirect_uri` not registered | Register the URI in your app settings | | `invalid_grant` | Expired/replayed auth code or bad PKCE | Restart the OAuth flow | | `access_denied` | Developer subscription inactive | Check your subscription status | | `invalid_token` (401 on /mcp) | JWT expired or invalid | Refresh the access token | ## Tools Overview URL: https://www.fieldmcp.com/docs/tools export const metadata = { title: 'Tools Overview', description: 'All available MCP tools in FieldMCP', alternates: { canonical: '/docs/tools' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('Tools Overview')}&description=${encodeURIComponent('All available MCP tools in FieldMCP')}` } } # Tools Overview FieldMCP exposes 11 MCP tools across 3 providers. All tools are read-only and idempotent — they never modify data. ## Response Format Every tool returns a JSON response with this structure: ### Success ```json { "error": false, "data": { ... }, "dataQuality": "COMPLETE", "missingData": [] } ``` ### Error ```json { "error": true, "code": "FIELD_NOT_FOUND", "message": "Field 'abc' not found in organization '123'", "retryable": false, "suggestedAction": "Verify the field ID using deere_list_resources" } ``` ## Data Quality Many tools return a `dataQuality` indicator: | Level | Meaning | |-------|---------| | `COMPLETE` | All data present, full confidence in results | | `PARTIAL` | Some optional data missing, results still valid but may be less precise | | `INSUFFICIENT` | Critical data missing, results may be unreliable | ## Error Codes ### Validation | Code | Retryable | Description | |------|-----------|-------------| | `MISSING_REQUIRED_PARAM` | No | A required parameter was not provided | | `INVALID_PARAM_VALUE` | No | A parameter has an invalid value | | `INVALID_PARAM_TYPE` | No | A parameter has the wrong type | ### Authentication | Code | Retryable | Description | |------|-----------|-------------| | `TOKEN_EXPIRED` | No | OAuth token expired — farmer needs to re-authorize | | `TOKEN_REVOKED` | No | OAuth token was revoked | | `PROVIDER_NOT_CONNECTED` | No | Farmer hasn't connected this provider | ### Rate Limiting | Code | Retryable | Description | |------|-----------|-------------| | `RATE_LIMIT_ORG` | Yes | Per-org rate limit exceeded ([details](/docs/rate-limits)) | | `RATE_LIMIT_PROVIDER` | Yes | Provider's rate limit exceeded | ### Provider | Code | Retryable | Description | |------|-----------|-------------| | `PROVIDER_UNAVAILABLE` | Yes | Provider API is down (~30s retry) | | `PROVIDER_TIMEOUT` | Yes | Provider API timed out | | `PROVIDER_ERROR` | Depends | Generic provider error (5xx retryable, 4xx not) | ### Resource | Code | Retryable | Description | |------|-----------|-------------| | `RESOURCE_NOT_FOUND` | No | Requested resource doesn't exist | | `FIELD_NOT_FOUND` | No | Field doesn't exist | | `ORG_NOT_FOUND` | No | Organization doesn't exist | | `EQUIPMENT_NOT_FOUND` | No | Equipment doesn't exist | ## Providers - [**John Deere**](/docs/tools/deere/list-resources) — List resources, field overviews, equipment status, operation search - [**Farm Intelligence**](/docs/tools/intelligence/diagnose-field) — Field diagnosis, yield analysis, field comparison, action plans, rule lookup - [**Weather**](/docs/tools/weather/get-conditions) — Historical and forecast weather with GDD, precipitation, temperature > See [Error Handling](/docs/errors) for recovery patterns covering all 18 error codes. ## Rate Limits URL: https://www.fieldmcp.com/docs/rate-limits export const metadata = { title: 'Rate Limits', description: 'Per-org rate limits, HTTP 429 handling, and scaling', alternates: { canonical: '/docs/rate-limits' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('Rate Limits')}&description=${encodeURIComponent('Per-org rate limits, HTTP 429 handling, and scaling')}` } } # Rate Limits FieldMCP uses a per-org rate limit model. Each connected John Deere organization adds its own quota. Connect more orgs, get more capacity. ## Limits | Limit | Per org | 5 orgs | 10 orgs | |-------|---------|--------|---------| | Monthly requests | 17,000 | 85,000 | 170,000 | | Per-minute requests | 100 | 500 | 1,000 | Limits scale linearly with connected organizations. There is no per-developer aggregate cap beyond the sum of your connected orgs. ## What Counts as a Request Each MCP tool call to the gateway counts as one request. This includes all tools: listing fields, getting boundaries, running diagnostics, fetching weather. **Requests that don't count:** failed requests due to rate limiting (HTTP 429) and validation errors (`MISSING_REQUIRED_PARAM`, `INVALID_PARAM_VALUE`, etc.) are not counted against your quota. For pricing details, see [Pricing](/docs/pricing). ## What You'll See at the Limit When your per-minute or monthly limit is exceeded, the gateway returns: - **HTTP 429** status code - A JSON error body with `rateLimits` metadata ```json { "error": "Rate limit exceeded. Try again in 12 seconds.", "errorCode": 429, "rateLimits": { "minuteRemaining": 0, "minuteResetAt": 1712345678000, "monthlyRemaining": 4200, "monthlyResetAt": 1714521600000 } } ``` ### The `X-RateLimit-Remaining` Header Every successful response includes an `X-RateLimit-Remaining` header showing how many per-minute requests you have left. Use this to throttle proactively instead of waiting for a 429. ``` HTTP/1.1 200 OK X-RateLimit-Remaining: 87 X-Request-Id: req-abc123 ``` When `X-RateLimit-Remaining` drops below 10, slow down. When it hits 0, the next request will return 429. ## Recovery Use exponential backoff when you hit a 429: ```typescript async function callWithBackoff(fn: () => Promise, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { const response = await fn(); if (response.status !== 429) return response; const body = await response.json(); const resetAt = body.rateLimits?.minuteResetAt; const waitMs = resetAt ? Math.max(0, resetAt - Date.now()) + Math.random() * 1000 : (2 ** attempt) * 1000 + Math.random() * 1000; await new Promise(resolve => setTimeout(resolve, waitMs)); } throw new Error('Rate limit exceeded after retries'); } ``` **Proactive throttling** is better than reactive backoff. Monitor `X-RateLimit-Remaining` and space your requests to stay under the limit: ```typescript const remaining = parseInt(response.headers.get('X-RateLimit-Remaining') ?? '100'); if (remaining < 10) { await new Promise(resolve => setTimeout(resolve, 2000)); // slow down } ``` ## Scaling Need more capacity? Connect more farm organizations. Each org adds 17,000 monthly requests and 100 requests per minute. | Orgs | Monthly cost | Monthly requests | Per-minute | |------|-------------|-----------------|------------| | 1 | $29 | 17,000 | 100 | | 5 | $145 | 85,000 | 500 | | 10 | $261 (10% volume discount) | 170,000 | 1,000 | | 25 | $652.50 | 425,000 | 2,500 | For enterprise-scale needs beyond 25 orgs, [contact sales](mailto:sales@fieldmcp.com). ## Provider Rate Limits John Deere has its own API rate limits, separate from FieldMCP's. When the gateway hits a Deere rate limit, it retries automatically with exponential backoff before surfacing the error to your MCP client. If the gateway exhausts its retries, you'll see a `RATE_LIMIT_PROVIDER` error code in the MCP tool response (not an HTTP 429). This means Deere itself is throttling. Wait the `retryAfter` seconds and try again. See [Error Handling](/docs/errors) for the full error code reference. ## Error Handling URL: https://www.fieldmcp.com/docs/errors export const metadata = { title: 'Error Handling', description: 'Every error code, what triggers it, and how to recover', alternates: { canonical: '/docs/errors' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('Error Handling')}&description=${encodeURIComponent('Every error code, what triggers it, and how to recover')}` } } # Error Handling Every FieldMCP tool returns either a success response or a structured error in the MCP `content` array with `isError: true`. Errors include machine-readable codes, human-readable messages, and recovery hints so AI assistants can reason about what went wrong. > **Rate limit errors** are returned as HTTP 429 with the `X-RateLimit-Remaining` header, not as tool-level error codes. See [Rate Limits](/docs/rate-limits) for that path. ## Error Response Shape When a tool call fails, the response includes a JSON object with these fields: ```json { "error": true, "code": "FIELD_NOT_FOUND", "message": "field 'xyz' not found", "retryable": false, "suggestedAction": "Use deere_list_resources with resourceType='fields' to find valid field IDs.", "requestId": "req-abc123" } ``` ### All Fields | Field | Type | Always present | Description | |-------|------|---------------|-------------| | `error` | `true` | Yes | Distinguishes errors from success responses | | `code` | string | Yes | Machine-readable error code (see tables below) | | `message` | string | Yes | Human-readable description | | `retryable` | boolean | Yes | Whether retrying the same request may succeed | | `suggestedAction` | string | Usually | Recovery hint for the AI assistant or developer | | `requestId` | string | Sometimes | For support escalation | | `param` | string | Validation errors | Which parameter failed | | `providedValue` | any | Validation errors | What was provided | | `expectedType` | string | Validation errors | What was expected | | `retryAfter` | number | Rate limit errors | Seconds until retry is allowed | | `provider` | string | Auth/provider errors | Which provider (e.g., "John Deere") | | `missingScopes` | string[] | Missing scope errors | Which OAuth scopes are needed | | `resourceId` | string | Resource errors | ID of the resource not found | | `resourceType` | string | Resource errors | Type: `field`, `organization`, `equipment`, `farm`, `operation`, `boundary` | | `succeeded` | array | Partial success | Items that completed successfully | | `failed` | array | Partial success | Items that failed with their error codes | | `missingData` | array | Data quality errors | What data is missing and its impact | ## Error Codes ### Validation Errors These fire when the tool call has invalid input. Not retryable. Fix the input and try again. | Code | When it fires | Recovery | |------|--------------|----------| | `MISSING_REQUIRED_PARAM` | A required parameter was not provided | Check the tool's parameter table. Provide the missing parameter. | | `INVALID_PARAM_VALUE` | A parameter has a value outside the allowed range or set | Check the allowed values. The `providedValue` and `expectedType` fields tell you exactly what was wrong. | | `INVALID_PARAM_TYPE` | A parameter has the wrong type (e.g., string instead of number) | Fix the type. The `expectedType` field shows what's needed. | | `MUTUALLY_EXCLUSIVE_PARAMS` | Two parameters that can't be used together were both provided | Remove one of the conflicting parameters. The `message` names both. | ### Authentication Errors These fire when the farmer's connection to a provider is broken. Not retryable by the AI assistant. The farmer needs to take action in the [Dashboard](/dashboard/connections). | Code | When it fires | Recovery | |------|--------------|----------| | `TOKEN_EXPIRED` | The farmer's John Deere access token has expired and could not be refreshed | **This is the farmer's Deere token, not your JWT.** The farmer needs to re-authorize John Deere access in the dashboard. | | `TOKEN_REVOKED` | The farmer revoked access in their John Deere account | The farmer needs to re-connect their John Deere account in the dashboard. | | `MISSING_SCOPE` | The farmer's connection lacks required OAuth scopes | The farmer needs to re-authorize with the required scopes (listed in `missingScopes`). | | `PROVIDER_NOT_CONNECTED` | The farmer hasn't connected the requested provider | The farmer needs to connect their account in the dashboard before using tools for that provider. | ### Rate Limiting | Code | When it fires | Recovery | |------|--------------|----------| | `RATE_LIMIT_ORG` | Tool-level escape hatch for per-org rate limiting. **Currently not emitted in production.** Actual rate limits surface as HTTP 429. | See [Rate Limits](/docs/rate-limits). Wait `retryAfter` seconds. | | `RATE_LIMIT_PROVIDER` | John Deere's own API rate limit was hit. The gateway retries automatically before surfacing this. | Wait `retryAfter` seconds. The provider is temporarily throttling requests. | ### Resource Errors These fire when the requested data doesn't exist. Not retryable with the same input. | Code | When it fires | Recovery | |------|--------------|----------| | `RESOURCE_NOT_FOUND` | A generic resource lookup failed | Use `deere_list_resources` to discover available resources. | | `FIELD_NOT_FOUND` | The specified field doesn't exist in the organization | Use `deere_list_resources` with `resourceType='fields'` to find valid field IDs. | | `ORG_NOT_FOUND` | The specified organization doesn't exist | Use `deere_list_resources` with `resourceType='organizations'` to find valid org IDs. | | `EQUIPMENT_NOT_FOUND` | The specified equipment doesn't exist | Use `deere_list_resources` with `resourceType='equipment'` to find valid equipment IDs. | | `BOUNDARY_NOT_FOUND` | The requested boundary doesn't exist for the field | Use `deere_list_resources` with `resourceType='boundaries'` and the field's `orgId` to find valid boundary IDs for that field. | ### Provider Errors These fire when the upstream provider (John Deere) has issues. May be retryable. | Code | Retryable | When it fires | Recovery | |------|-----------|--------------|----------| | `PROVIDER_UNAVAILABLE` | Yes | John Deere API is down or unreachable | Wait `retryAfter` seconds (default 30s). Provider may be experiencing an outage. | | `PROVIDER_TIMEOUT` | Yes | John Deere API request timed out | Retry. Consider requesting less data (shorter date range, fewer include options). | | `PROVIDER_ERROR` | 5xx: Yes, 4xx: No | John Deere returned an unexpected error | For 5xx: retry shortly. For 4xx: check the request parameters. | ### Data Quality Errors These fire when the field exists but lacks sufficient data for the requested analysis. | Code | When it fires | Recovery | |------|--------------|----------| | `INSUFFICIENT_DATA` | Critical data is missing for the analysis | Check the `missingData` array. Each entry lists what's missing, its impact (`required` / `degraded` / `optional`), and a message explaining what to do. | | `NO_DATA_FOR_PERIOD` | No data exists for the requested time period | Try a different time period. Use `deere_search_operations` to discover what data is available. | ### Partial Failures | Code | When it fires | Recovery | |------|--------------|----------| | `PARTIAL_SUCCESS` | Some items in a batch succeeded, others failed | Read the `succeeded` array for completed items. Read the `failed` array for items that need attention. Each failed item has its own `code` and `message`. If any failures are retryable (`PROVIDER_TIMEOUT`, `PROVIDER_UNAVAILABLE`, `RATE_LIMIT_PROVIDER`), retry those items. | ### Internal Errors | Code | When it fires | Recovery | |------|--------------|----------| | `INTERNAL_ERROR` | An unexpected error occurred in the gateway | Include the `requestId` when contacting support. This should not happen in normal operation. | ## Recovery Decision Tree ``` Is the error retryable? ├── Yes → Wait `retryAfter` seconds, then retry │ ├── Still failing after 3 retries → Stop, surface the error │ └── Succeeds → Continue └── No → Check the error category: ├── Validation → Fix the input parameters ├── Auth → Farmer needs to re-authorize in the dashboard ├── Resource → Use deere_list_resources to find valid IDs ├── Data Quality → Try different time period or provide more input data ├── Partial → Process succeeded items, retry or report failed items └── Internal → Contact support with requestId ``` ## Retry Strategy For retryable errors, use exponential backoff with jitter: ``` attempt 1: wait retryAfter seconds (from the error response) attempt 2: wait retryAfter × 2 + random(0-1000ms) attempt 3: wait retryAfter × 4 + random(0-1000ms) give up after 3 attempts ``` If the error includes a `retryAfter` field, always respect it. If not, start with 2 seconds. ## Common Recovery Patterns ### "TOKEN_EXPIRED" keeps firing This means the farmer's John Deere session has expired and the gateway couldn't auto-refresh it. The farmer needs to visit the [Dashboard](/dashboard/connections) and click "Reconnect" for John Deere. The access token typically lasts ~90 days. If this fires repeatedly, check whether the farmer revoked access in their John Deere account. ### "PROVIDER_UNAVAILABLE" on all requests John Deere's API may be experiencing an outage. Check [John Deere's status page](https://www.deere.com/en/technology-products/precision-ag-technology/) or wait 5-10 minutes. The gateway automatically retries with backoff before surfacing this error. ### "PARTIAL_SUCCESS" on batch operations Some items succeeded, some failed. The `succeeded` and `failed` arrays give you the full picture. Process the successful results immediately. For failed items, check if their individual error codes are retryable. If yes, retry just those items. If no, report the failures to the user with the specific error messages. --- See [Rate Limits](/docs/rate-limits) for HTTP 429 recovery. See individual [tool pages](/docs/tools) for the specific errors each tool can emit. ## List Resources URL: https://www.fieldmcp.com/docs/tools/deere/list-resources export const metadata = { title: 'deere_list_resources', description: 'List John Deere resources by type — organizations, fields, equipment, farms, and more', alternates: { canonical: '/docs/tools/deere/list-resources' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('deere_list_resources')}&description=${encodeURIComponent('List John Deere resources by type — organizations, fields, equipment, farms, and more')}` } } # deere_list_resources List John Deere resources by type. Start with `resourceType='organizations'` to discover available organizations, then use the `orgId` to query other resource types. ## Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `resourceType` | enum | Yes | — | `organizations`, `fields`, `equipment`, `farms`, `clients`, `assets`, `boundaries`, `operators` | | `orgId` | string | No | — | Organization ID. Required for all resource types except `organizations`. | | `limit` | number | No | 50 | Results per page (1-100) | | `offset` | number | No | 0 | Pagination offset | | `filters` | object | No | — | Optional filters (see below) | ### Filters | Filter | Type | Description | |--------|------|-------------| | `userName` | string | Filter by user name | | `orgName` | string | Filter by organization name (max 128 chars) | | `fieldName` | string | Filter by field name (max 128 chars) | | `recordFilter` | enum | `AVAILABLE`, `ARCHIVED`, or `ALL` | | `fieldId` | string | Filter boundaries/operations to a specific field | ## Usage ### Discover Organizations ```json { "resourceType": "organizations" } ``` ### List Fields in an Organization ```json { "resourceType": "fields", "orgId": "123456" } ``` ### List Equipment with Pagination ```json { "resourceType": "equipment", "orgId": "123456", "limit": 20, "offset": 0 } ``` ## Response The response shape depends on the `resourceType`: ### Organizations ```json { "error": false, "data": [ { "id": "org-uuid", "externalId": "123456", "provider": "john_deere", "name": "Smith Farms" } ] } ``` ### Fields ```json { "error": false, "data": [ { "id": "field-uuid", "externalId": "abc123", "provider": "john_deere", "organizationId": "123456", "name": "North 40", "acres": 40.5, "activeCrop": "corn" } ] } ``` ### Equipment ```json { "error": false, "data": [ { "id": "eq-uuid", "externalId": "eq123", "provider": "john_deere", "organizationId": "123456", "name": "8R 370", "type": "tractor", "make": "John Deere", "model": "8R 370", "year": 2023 } ] } ``` ## Errors | Code | Cause | |------|-------| | `MISSING_REQUIRED_PARAM` | `orgId` is required for non-organization resource types | | `RESOURCE_NOT_FOUND` | Organization not found | | `BOUNDARY_NOT_FOUND` | `resourceType='boundaries'` requested for a field that has no boundary | | `TOKEN_EXPIRED` | John Deere token expired | > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Get Field Overview URL: https://www.fieldmcp.com/docs/tools/deere/get-field-overview export const metadata = { title: 'deere_get_field_overview', description: 'Get comprehensive field data — details, boundary, operations, flags, and guidance', alternates: { canonical: '/docs/tools/deere/get-field-overview' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('deere_get_field_overview')}&description=${encodeURIComponent('Get comprehensive field data — details, boundary, operations, flags, and guidance')}` } } # deere_get_field_overview Get comprehensive field data in a single call. Returns field details with optional boundary geometry, recent operations, flags, and guidance lines. ## Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `orgId` | string | Yes | — | Organization ID | | `fieldId` | string | Yes | — | Field ID | | `include` | string[] | No | `["details", "boundary"]` | Sections to include: `details`, `boundary`, `operations`, `flags`, `guidance` | | `operationsDateRange` | object | No | — | `{ startDate, endDate }` in YYYY-MM-DD format | | `operationsLimit` | number | No | 10 | Max operations to return (1-50) | ## Usage ### Basic Field Details ```json { "orgId": "123", "fieldId": "abc" } ``` ### Full Field Overview with Operations ```json { "orgId": "123", "fieldId": "abc", "include": ["details", "boundary", "operations", "flags"], "operationsDateRange": { "startDate": "2025-01-01" } } ``` ## Response ```json { "error": false, "data": { "field": { "id": "field-uuid", "externalId": "abc", "provider": "john_deere", "organizationId": "123", "name": "North 40", "acres": 40.5, "activeCrop": "corn" }, "canonicalFieldId": "uuid-stable-across-providers", "boundary": { "type": "Polygon", "coordinates": [[[...], [...], ...]] }, "operations": [ { "id": "op-uuid", "fieldId": "abc", "date": "2025-04-15", "operationType": "planting", "crop": "corn", "details": { "variety": "DKC62-08", "seedingRate": 34000 } } ], "flags": [ { "id": "flag-uuid", "fieldId": "abc", "name": "Tile Inlet", "coordinates": { "lat": 42.0, "lon": -93.6 }, "flagType": "drainage" } ] }, "dataQuality": "COMPLETE" } ``` The `canonicalFieldId` is a stable UUID assigned when the field is synced — use it to reference fields consistently across providers. ## Partial Success If some sections fail to load (e.g., boundary times out but details succeed), the tool returns `dataQuality: "PARTIAL"` with a `missingData` array explaining what failed: ```json { "dataQuality": "PARTIAL", "missingData": [ { "field": "boundary", "impact": "degraded", "message": "Boundary request timed out" } ] } ``` ## Errors | Code | Cause | |------|-------| | `FIELD_NOT_FOUND` | Field doesn't exist in this organization | | `TOKEN_EXPIRED` | John Deere token expired | | `PROVIDER_TIMEOUT` | John Deere API timed out | > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Get Equipment Status URL: https://www.fieldmcp.com/docs/tools/deere/get-equipment-status export const metadata = { title: 'deere_get_equipment_status', description: 'Get equipment details with telemetry — location, alerts, and engine hours', alternates: { canonical: '/docs/tools/deere/get-equipment-status' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('deere_get_equipment_status')}&description=${encodeURIComponent('Get equipment details with telemetry — location, alerts, and engine hours')}` } } # deere_get_equipment_status Get equipment details with optional telemetry data. Returns machine info with current location, alerts, and engine hours. ## Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `equipmentId` | string | Yes | — | Equipment ID | | `orgId` | string | No | — | Organization ID (for context) | | `include` | string[] | No | `["details", "location"]` | Sections: `details`, `location`, `alerts`, `engineHours` | | `dateRange` | object | No | — | `{ startDate, endDate }` for historical telemetry | ## Usage ### Current Status ```json { "equipmentId": "eq123" } ``` ### Full Telemetry with Alerts ```json { "equipmentId": "eq123", "include": ["details", "location", "alerts", "engineHours"] } ``` ## Response ```json { "error": false, "data": { "equipment": { "id": "eq-uuid", "externalId": "eq123", "provider": "john_deere", "organizationId": "123", "name": "8R 370", "type": "tractor", "make": "John Deere", "model": "8R 370", "year": 2023 }, "currentLocation": { "id": "loc-uuid", "equipmentId": "eq123", "timestamp": "2025-03-15T14:30:00Z", "coordinates": { "lat": 42.0, "lon": -93.6 }, "speed": 5.2, "heading": 270 }, "alerts": [ { "id": "alert-uuid", "equipmentId": "eq123", "alertType": "maintenance", "severity": "medium", "message": "Oil change due in 50 hours", "timestamp": "2025-03-14T10:00:00Z", "acknowledged": false } ], "engineHours": { "id": "eh-uuid", "equipmentId": "eq123", "hours": 2450.5, "timestamp": "2025-03-15T14:30:00Z" } }, "dataQuality": "COMPLETE" } ``` ## Alert Severity Levels | Severity | Meaning | |----------|---------| | `low` | Informational — no action needed | | `medium` | Attention needed soon | | `high` | Action required | | `critical` | Immediate attention required | ## Errors | Code | Cause | |------|-------| | `EQUIPMENT_NOT_FOUND` | Equipment doesn't exist | | `TOKEN_EXPIRED` | John Deere token expired | | `PROVIDER_TIMEOUT` | API timed out | > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Search Operations URL: https://www.fieldmcp.com/docs/tools/deere/search-operations export const metadata = { title: 'deere_search_operations', description: 'Search field operations — planting, harvest, applications, and tillage', alternates: { canonical: '/docs/tools/deere/search-operations' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('deere_search_operations')}&description=${encodeURIComponent('Search field operations — planting, harvest, applications, and tillage')}` } } # deere_search_operations Search field operations across an organization or for a specific field. Returns crop, dates, area, and type-specific details for planting, harvest, application, and tillage operations. ## Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `orgId` | string | Yes | — | Organization ID | | `fieldId` | string | No | — | Filter to a specific field | | `operationType` | enum | No | `all` | `planting`, `harvest`, `application`, `tillage`, or `all` | | `dateRange` | object | No | — | `{ startDate, endDate }` in YYYY-MM-DD format | | `limit` | number | No | 50 | Results per page (1-100) | | `offset` | number | No | 0 | Pagination offset | ## Usage ### All Operations for a Field ```json { "orgId": "123", "fieldId": "abc" } ``` ### Harvest Data for a Season ```json { "orgId": "123", "operationType": "harvest", "dateRange": { "startDate": "2025-09-01", "endDate": "2025-12-31" } } ``` ## Response ```json { "error": false, "data": { "operations": [ { "id": "op-uuid", "fieldId": "abc", "date": "2025-10-15", "operationType": "harvest", "crop": "corn", "area": 40.5, "yieldPerAcre": 185.3, "moisture": 15.2, "totalYield": 7504.65 }, { "id": "op-uuid-2", "fieldId": "abc", "date": "2025-04-20", "operationType": "planting", "crop": "corn", "area": 40.5, "variety": "DKC62-08", "seedingRate": 34000, "population": 34000 } ], "pagination": { "total": 2, "offset": 0, "limit": 50, "hasMore": false } } } ``` ## Operation-Specific Fields ### Planting | Field | Description | |-------|-------------| | `variety` | Seed variety | | `seedingRate` | Seeds per acre | | `population` | Plant population | ### Harvest | Field | Description | |-------|-------------| | `yieldPerAcre` | Bushels per acre | | `moisture` | Grain moisture percentage | | `totalYield` | Total bushels | ### Application | Field | Description | |-------|-------------| | `product` | Product name | | `productType` | `fertilizer`, `herbicide`, `insecticide`, `fungicide`, `other` | | `ratePerAcre` | Application rate | | `rateUnit` | Rate unit (e.g., lbs, gal) | ### Tillage | Field | Description | |-------|-------------| | `implement` | Tillage implement used | | `depth` | Tillage depth | ## Notes When searching across all fields in an organization (no `fieldId`), the tool queries up to 20 fields to avoid provider API limits. For large organizations, filter by `fieldId` for best results. ## Errors | Code | Cause | |------|-------| | `ORG_NOT_FOUND` | Organization doesn't exist | | `NO_DATA_FOR_PERIOD` | No operations found in date range | | `TOKEN_EXPIRED` | John Deere token expired | | `PROVIDER_TIMEOUT` | Try a shorter date range | > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Diagnose Field URL: https://www.fieldmcp.com/docs/tools/intelligence/diagnose-field export const metadata = { title: 'intel_diagnose_field', description: 'Run comprehensive field analysis with 140+ diagnostic rules', alternates: { canonical: '/docs/tools/intelligence/diagnose-field' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('intel_diagnose_field')}&description=${encodeURIComponent('Run comprehensive field analysis with 140+ diagnostic rules')}` } } # intel_diagnose_field Run comprehensive field analysis and return all triggered diagnostic rules. Provide field data (yield history, soil tests, etc.) and receive a prioritized action plan with evidence-backed recommendations. ## Parameters ### Required | Parameter | Type | Description | |-----------|------|-------------| | `fieldId` | string | Unique field identifier | | `crop` | enum | `corn`, `soybean`, or `wheat` | | `targetCropYear` | number | Year to analyze | ### Optional (improves analysis) | Parameter | Type | Description | |-----------|------|-------------| | `fieldName` | string | Human-readable field name | | `acres` | number | Field size | | `location` | object | `{ state, region, latitude?, longitude?, countyFIPS? }` | | `yieldHistory` | array | `[{ year, bushelsPerAcre, crop? }]` — ideally 5+ years | | `countyYieldHistory` | array | `[{ year, averageYield }]` — for benchmarking | | `soilTest` | object | pH, organic matter, phosphorus, potassium, CEC, texture, drainage | | `compactionAssessment` | object | Penetrometer readings, ribbon test results | | `drainageAssessment` | object | Saturation duration, tile drainage status | | `rotationHistory` | object | `{ history: [{ year, crop, tillage }] }` | | `plantingRecord` | object | Date, variety, population, row spacing | | `diseaseAssessments` | array | Disease observations with severity | | `pestCounts` | array | Pest observation data | The more data you provide, the higher the analysis confidence. ## Usage ### Minimal ```json { "fieldId": "field-001", "crop": "corn", "targetCropYear": 2025 } ``` ### With Yield and Soil Data ```json { "fieldId": "field-001", "fieldName": "North 40", "crop": "corn", "targetCropYear": 2025, "acres": 40, "yieldHistory": [ { "year": 2024, "bushelsPerAcre": 165 }, { "year": 2023, "bushelsPerAcre": 172 }, { "year": 2022, "bushelsPerAcre": 168 } ], "soilTest": { "testDate": "2024-10-15", "fieldId": "field-001", "pH": 6.1, "texture": "silt_loam", "drainageClass": "moderately_well_drained" } } ``` ## Response ```json { "error": false, "data": { "fieldId": "field-001", "fieldName": "North 40", "crop": "corn", "analysisDate": "2025-03-15T12:00:00Z", "overallConfidence": 0.72, "dataQuality": "PARTIAL", "diagnosticSummary": "3 issues identified. Primary concern: soil pH below optimal range.", "prioritizedActions": [ { "priority": 1, "type": "ph", "severity": "moderate", "rationale": "Per DEC-001: Correct pH before fertilizer application", "prerequisites_met": true }, { "priority": 2, "type": "nitrogen", "severity": "low", "rationale": "Yield history suggests potential nitrogen limitation", "prerequisites_met": true } ], "triggeredRules": [ { "ruleId": "NUT-003", "name": "Suboptimal pH Detection", "confidence": 0.95, "message": "Soil pH 6.1 is below optimal range for corn (6.3-6.8)" } ], "missingData": [ { "field": "compactionAssessment", "impact": "degraded", "message": "Cannot assess compaction without penetrometer data" } ] } } ``` ## Data Quality | Level | Meaning | |-------|---------| | `COMPLETE` | All recommended data provided | | `PARTIAL` | Some data missing — analysis runs but confidence is lower | | `INSUFFICIENT` | Critical data missing — results may be unreliable | Use [intel_get_rule_details](/docs/tools/intelligence/get-rule-details) to understand why a specific rule fired. > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Analyze Yield URL: https://www.fieldmcp.com/docs/tools/intelligence/analyze-yield export const metadata = { title: 'intel_analyze_yield', description: 'Focused yield trend analysis — variability, underperformance, and benchmarking', alternates: { canonical: '/docs/tools/intelligence/analyze-yield' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('intel_analyze_yield')}&description=${encodeURIComponent('Focused yield trend analysis — variability, underperformance, and benchmarking')}` } } # intel_analyze_yield Focused yield trend analysis for a single field. Analyzes systemic underperformance vs county average, yield variability, consecutive year patterns, and baseline yield. ## Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `fieldId` | string | Yes | Field identifier | | `fieldName` | string | No | Human-readable name | | `acres` | number | No | Field size | | `yieldHistory` | array | Yes | `[{ year, bushelsPerAcre }]` — minimum 1, ideally 5+ years | | `countyYieldHistory` | array | No | `[{ year, averageYield }]` — enables benchmarking | | `countyFIPS` | string | No | County FIPS code for automatic benchmarks | ## Usage ```json { "fieldId": "field-001", "yieldHistory": [ { "year": 2024, "bushelsPerAcre": 165 }, { "year": 2023, "bushelsPerAcre": 172 }, { "year": 2022, "bushelsPerAcre": 168 }, { "year": 2021, "bushelsPerAcre": 155 }, { "year": 2020, "bushelsPerAcre": 170 } ], "countyYieldHistory": [ { "year": 2024, "averageYield": 180 }, { "year": 2023, "averageYield": 178 }, { "year": 2022, "averageYield": 176 }, { "year": 2021, "averageYield": 174 }, { "year": 2020, "averageYield": 175 } ] } ``` ## Response ```json { "error": false, "data": { "fieldId": "field-001", "yieldRecordCount": 5, "variabilityAnalysis": { "classificationLevel": "low", "standardDeviation": 5.8, "coefficientOfVariation": 3.5, "recommendation": "Yield is consistent — focus on incremental gains" }, "systemicIssueAnalysis": { "underperformancePercent": 5.7, "consistentUnderperformance": true, "recommendation": "Field consistently underperforms county average by 5.7%. Investigate soil or drainage issues." }, "triggeredRules": [ { "ruleId": "YLD-001", "name": "Systemic Underperformance Detection", "confidence": 0.95, "message": "Field underperforms county average by >5% consistently" } ], "dataQuality": "COMPLETE", "missingData": [] } } ``` ## Rules Analyzed | Rule | Description | |------|-------------| | YLD-001 | Systemic underperformance vs county average (>5%) | | YLD-002 | Yield variability classification (low/moderate/high/extreme) | | YLD-004 | Consecutive year decline patterns | | YLD-005 | Baseline yield calculation | > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Compare Fields URL: https://www.fieldmcp.com/docs/tools/intelligence/compare-fields export const metadata = { title: 'intel_compare_fields', description: 'Compare multiple fields side-by-side for prioritization', alternates: { canonical: '/docs/tools/intelligence/compare-fields' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('intel_compare_fields')}&description=${encodeURIComponent('Compare multiple fields side-by-side for prioritization')}` } } # intel_compare_fields Compare multiple fields side-by-side. Runs diagnosis on each field and produces a comparison table showing data quality, triggered rules, top priority action, and overall confidence. ## Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `fields` | array | Yes | 2-10 field objects (same schema as `intel_diagnose_field`) | Each field object requires at minimum: `fieldId`, `crop`, `targetCropYear`. ## Usage ```json { "fields": [ { "fieldId": "field-001", "fieldName": "North 40", "crop": "corn", "targetCropYear": 2025, "yieldHistory": [ { "year": 2024, "bushelsPerAcre": 165 } ] }, { "fieldId": "field-002", "fieldName": "South 80", "crop": "corn", "targetCropYear": 2025, "yieldHistory": [ { "year": 2024, "bushelsPerAcre": 140 } ] } ] } ``` ## Response ```json { "error": false, "data": { "fieldCount": 2, "comparison": [ { "fieldId": "field-001", "fieldName": "North 40", "crop": "corn", "dataQuality": "PARTIAL", "overallConfidence": 0.65, "triggeredRuleCount": 2, "topPriorityAction": { "action": "Soil test recommended" }, "diagnosticSummary": "2 issues identified" }, { "fieldId": "field-002", "fieldName": "South 80", "crop": "corn", "dataQuality": "PARTIAL", "overallConfidence": 0.60, "triggeredRuleCount": 5, "topPriorityAction": { "action": "Investigate yield decline" }, "diagnosticSummary": "5 issues identified" } ], "priorityRanking": [ { "fieldId": "field-002", "priority": "high", "reason": "5 triggered rules — needs immediate attention" }, { "fieldId": "field-001", "priority": "low", "reason": "2 triggered rules — minor issues" } ] } } ``` ## Priority Classification | Priority | Triggered Rules | Meaning | |----------|-----------------|---------| | `high` | More than 5 | Needs immediate attention | | `medium` | 3-5 | Should investigate soon | | `low` | Fewer than 3 | Minor issues | > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Get Action Plan URL: https://www.fieldmcp.com/docs/tools/intelligence/get-action-plan export const metadata = { title: 'intel_get_action_plan', description: 'Get a prioritized intervention plan based on yield limiting factors', alternates: { canonical: '/docs/tools/intelligence/get-action-plan' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('intel_get_action_plan')}&description=${encodeURIComponent('Get a prioritized intervention plan based on yield limiting factors')}` } } # intel_get_action_plan Get a prioritized action plan following agronomic triage principles. Provide identified yield limiting factors and receive an ordered intervention sequence with rationale. ## Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `yieldLimitingFactors` | array | Yes | Array of `{ type, severity }` objects | | `budgetPerAcre` | number | No | Budget constraint in dollars per acre | ### Factor Types `drainage`, `compaction`, `ph`, `nitrogen`, `phosphorus`, `potassium`, `micronutrients`, `variety`, `management` ### Severity Levels `low`, `moderate`, `severe` ## Usage ```json { "yieldLimitingFactors": [ { "type": "drainage", "severity": "moderate" }, { "type": "nitrogen", "severity": "severe" }, { "type": "ph", "severity": "low" } ], "budgetPerAcre": 150 } ``` ## Response ```json { "error": false, "data": { "prioritizedActions": [ { "priority": 1, "type": "drainage", "severity": "moderate", "rationale": "Per DEC-001: Drainage is highest priority (physical limitation)", "prerequisitesMet": true }, { "priority": 2, "type": "ph", "severity": "low", "rationale": "Per DEC-001: Correct pH before fertilizer application", "prerequisitesMet": true }, { "priority": 3, "type": "nitrogen", "severity": "severe", "rationale": "Per DEC-001: Address macronutrients after physical and pH issues", "prerequisitesMet": true } ], "triggeredRules": [ { "ruleId": "DEC-001", "name": "Yield Limiting Factor Triage", "message": "Prioritized 3 factors using agronomic triage hierarchy" } ], "budgetConstraint": "moderate", "dataQuality": "COMPLETE" } } ``` ## Triage Hierarchy (DEC-001) Actions are prioritized following this agronomic principle: **address physical issues before chemical, chemical before biological**. | Priority | Factor | Rationale | |----------|--------|-----------| | 1 | Drainage | Physical limitation — nothing else works if water can't drain | | 2 | Compaction | Physical limitation — restricts root growth | | 3 | pH | Chemical availability — nutrients are locked out at wrong pH | | 4 | Nitrogen | Macronutrient | | 5 | Phosphorus | Macronutrient | | 6 | Potassium | Macronutrient | | 7 | Micronutrients | Secondary nutrients | | 8 | Variety | Genetic potential | | 9 | Management | Agronomic practices | > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Get Rule Details URL: https://www.fieldmcp.com/docs/tools/intelligence/get-rule-details export const metadata = { title: 'intel_get_rule_details', description: 'Look up detailed information about a specific diagnostic rule', alternates: { canonical: '/docs/tools/intelligence/get-rule-details' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('intel_get_rule_details')}&description=${encodeURIComponent('Look up detailed information about a specific diagnostic rule')}` } } # intel_get_rule_details Look up detailed information about a specific diagnostic rule by ID. Use this to understand why a recommendation was made or to learn about specific thresholds. ## Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `ruleId` | string | Yes | Rule ID in format `XXX-NNN` (e.g., `SED-001`, `YLD-005`) | ## Usage ```json { "ruleId": "YLD-001" } ``` ## Response ```json { "error": false, "data": { "success": true, "ruleId": "YLD-001", "name": "Systemic Underperformance Detection", "category": "YLD", "categoryDescription": "Yield Analysis", "description": "Identifies fields consistently underperforming vs county average by >5%", "researchSource": "NASS/USDA yield trending", "confidence": 0.95 } } ``` ## Rule Categories | Prefix | Category | Description | |--------|----------|-------------| | `YLD` | Yield Analysis | Yield trends, variability, benchmarking | | `SED` | Seed Selection | Variety and hybrid recommendations | | `NUT` | Nutrient Management | Soil fertility and fertilizer | | `CMP` | Compaction | Soil compaction diagnosis | | `DRN` | Drainage | Water management | | `DIS` | Disease & Pest | Disease and pest identification | | `PLT` | Planting | Planting date, population, spacing | | `ROT` | Rotation | Crop rotation analysis | | `WTH` | Weather | Weather impact assessment | | `DAT` | Data Quality | Input data completeness | | `REC` | Recommendations | General recommendations | | `DEC` | Decision Prioritization | Action triage and sequencing | Use [intel_search_rules](/docs/tools/intelligence/search-rules) to browse all rules in a category. > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Search Rules URL: https://www.fieldmcp.com/docs/tools/intelligence/search-rules export const metadata = { title: 'intel_search_rules', description: 'Search and browse diagnostic rules by category or keyword', alternates: { canonical: '/docs/tools/intelligence/search-rules' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('intel_search_rules')}&description=${encodeURIComponent('Search and browse diagnostic rules by category or keyword')}` } } # intel_search_rules Search diagnostic rules by category or keyword. Browse all rules in a category or find rules related to a specific topic. ## Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `category` | enum | No | `YLD`, `SED`, `NUT`, `CMP`, `DRN`, `DIS`, `PLT`, `ROT`, `WTH`, `DAT`, `REC`, `DEC` | | `keyword` | string | No | Search in rule names and descriptions | | `limit` | number | No | Max results (1-50, default: 20) | If neither `category` nor `keyword` is provided, returns a category overview. ## Usage ### Browse a Category ```json { "category": "YLD" } ``` ### Search by Keyword ```json { "keyword": "drainage" } ``` ### Overview of All Categories ```json {} ``` ## Response ### Category Overview (no filters) ```json { "error": false, "data": { "mode": "overview", "totalRules": 142, "categories": [ { "prefix": "YLD", "name": "Yield Analysis", "ruleCount": 5 }, { "prefix": "SED", "name": "Seed Selection", "ruleCount": 12 }, { "prefix": "NUT", "name": "Nutrient Management", "ruleCount": 18 } ], "hint": "Use category or keyword to search specific rules" } } ``` ### Search Results ```json { "error": false, "data": { "mode": "search", "query": { "category": "YLD" }, "totalMatches": 5, "returned": 5, "rules": [ { "ruleId": "YLD-001", "name": "Systemic Underperformance Detection", "description": "Identifies fields consistently underperforming vs county average", "category": "YLD" }, { "ruleId": "YLD-002", "name": "Yield Variability Classification", "description": "Classifies yield consistency as low/moderate/high/extreme", "category": "YLD" } ] } } ``` This tool always returns a valid response — an empty results array if no matches are found. > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Get Conditions URL: https://www.fieldmcp.com/docs/tools/weather/get-conditions export const metadata = { title: 'weather_get_conditions', description: 'Fetch weather data — temperature, precipitation, GDD, and soil temperature', alternates: { canonical: '/docs/tools/weather/get-conditions' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('weather_get_conditions')}&description=${encodeURIComponent('Fetch weather data — temperature, precipitation, GDD, and soil temperature')}` } } # weather_get_conditions Fetch weather conditions for a location and date range. Supports both historical data (from 1940) and forecasts (up to 16 days ahead). ## Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `latitude` | number | Yes | — | Latitude (-90 to 90) | | `longitude` | number | Yes | — | Longitude (-180 to 180) | | `startDate` | string | Yes | — | Start date (YYYY-MM-DD) | | `endDate` | string | Yes | — | End date (YYYY-MM-DD) | | `include` | string[] | No | `["gdd", "precipitation", "temperature"]` | Data to include: `gdd`, `precipitation`, `temperature`, `soil_temperature` | **Constraints:** - Maximum date range: 2 years (730 days) - `endDate` must be after `startDate` - Soil temperature is only available for recent dates ## Usage ### Growing Season Weather ```json { "latitude": 42.0, "longitude": -93.6, "startDate": "2025-05-01", "endDate": "2025-09-30", "include": ["gdd", "precipitation", "temperature"] } ``` ### Current Forecast ```json { "latitude": 42.0, "longitude": -93.6, "startDate": "2025-03-16", "endDate": "2025-03-30" } ``` ## Response ```json { "error": false, "data": { "location": { "latitude": 42.0, "longitude": -93.6, "timezone": "America/Chicago" }, "dateRange": { "startDate": "2025-05-01", "endDate": "2025-09-30" }, "daily": { "dates": ["2025-05-01", "2025-05-02", "..."], "temperature": { "high_celsius": [22.5, 23.1], "high_fahrenheit": [72.5, 73.6], "low_celsius": [10.2, 11.0], "low_fahrenheit": [50.4, 51.8], "average_celsius": [16.3, 17.0], "average_fahrenheit": [61.4, 62.7] }, "precipitation": { "total_mm": [0, 5.2, 0, 2.1], "total_inches": [0, 0.2, 0, 0.08], "rain_days": 65 }, "gdd": { "base_temp_fahrenheit": 50, "daily": [8.5, 8.7, 8.9], "accumulated": [8.5, 17.2, 26.1] } } } } ``` ## GDD (Growing Degree Days) GDD is calculated using base 50F for corn: ``` GDD = max(0, (high + low) / 2 - base_temp) ``` The `accumulated` array gives cumulative GDD from the start date — useful for tracking crop development stages. ## Use Cases | Scenario | Parameters | |----------|-----------| | Check planting conditions | Temperature + soil_temperature for next 7 days | | Track crop development | GDD accumulated over growing season | | Irrigation decisions | Precipitation totals for past 14 days | | Frost risk assessment | Temperature lows for forecast period | | Season comparison | Same date range across multiple years | ## Data Source Weather data is sourced from [Open-Meteo](https://open-meteo.com), a free public weather API with global coverage. ## Errors | Code | Cause | |------|-------| | `INVALID_PARAM_VALUE` | Invalid coordinates, date format, or date range >730 days | | `PROVIDER_ERROR` | Open-Meteo API error | > See [Error Handling](/docs/errors) for recovery patterns and retry strategies. ## Pricing URL: https://www.fieldmcp.com/docs/pricing export const metadata = { title: 'Pricing', description: 'Per-org pricing for developer capacity planning', alternates: { canonical: '/docs/pricing' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('Pricing')}&description=${encodeURIComponent('Per-org pricing for developer capacity planning')}` } } # Pricing Per-org pricing for capacity planning. > This page summarizes pricing in developer terms. For the full breakdown including FAQ and interactive calculator, see [Pricing](/pricing). ## The Model FieldMCP uses flat per-org pricing. Each connected John Deere organization costs the same, and each org adds its own API quota. | | Monthly | Annual (17% off) | |---|---|---| | **Per org** | $29/month | $290/year | | **10+ orgs** (10% volume discount) | $26.10/month | $261/year | Every approved account includes a **14-day free trial**. After your access request is approved, enter your card to start the trial — you won't be charged until day 15. ## What's an "Org"? An org is a connected John Deere organization — a farm, co-op, or dealership the farmer has access to in their John Deere account. When a farmer authorizes your app, you can connect one or more of their organizations. More connected orgs = more API capacity and more farm data to work with. ## What Counts as a Request Each MCP tool call to the FieldMCP gateway counts as one request. This includes all tools: listing fields, getting boundaries, running diagnostics, fetching weather, analyzing yield. **Requests that don't count:** failed requests due to rate limiting (HTTP 429) and input validation errors are not counted against your quota. ## Capacity per Org Each connected organization adds: - **17,000 requests per month** - **100 requests per minute** See [Rate Limits](/docs/rate-limits) for details on HTTP 429 handling and scaling. ## Worked Examples | Connected orgs | Monthly cost | Annual cost | Monthly requests | Per-minute | |---|---|---|---|---| | 1 | $29 | $290 | 17,000 | 100 | | 5 | $145 | $1,450 | 85,000 | 500 | | 10 | $261 | $2,610 | 170,000 | 1,000 | | 25 | $652.50 | $6,525 | 425,000 | 2,500 | ## Get Started - [Request access](https://fieldmcp.com/signup) — 14-day trial starts after approval, no charge until day 15 - [Contact sales](mailto:sales@fieldmcp.com) — for enterprise-scale deployments (25+ orgs) - [Full pricing details](/pricing) — FAQ, calculator, and plan comparison ## Changelog URL: https://www.fieldmcp.com/docs/changelog export const metadata = { title: 'Changelog', description: 'What changed in FieldMCP and when', alternates: { canonical: '/docs/changelog' }, openGraph: { images: `/api/docs-og?title=${encodeURIComponent('Changelog')}&description=${encodeURIComponent('What changed in FieldMCP and when')}` } } # Changelog Notable changes to FieldMCP. This changelog is maintained manually — notable changes are added on merge. --- ## Unreleased ### Changed - Renamed error code `RATE_LIMIT_ORG` (was `RATE_LIMIT_USER`). The previous name was a relic of pre-per-org billing. No production impact — rate limits surface as HTTP 429 with the `X-RateLimit-Remaining` header. ### Added - Error handling guide at [`/docs/errors`](/docs/errors) covering all 18 error codes with recovery patterns - Rate limits page at [`/docs/rate-limits`](/docs/rate-limits) documenting per-org quotas and HTTP 429 recovery - Pricing summary at [`/docs/pricing`](/docs/pricing) for developer capacity planning - Quickstart support for Cursor, Windsurf, and custom MCP clients (was Claude Desktop only) - Full-text keyword search across docs via the command palette --- ## 2026-04 — Stripe Billing (Wave 2) ### Added - Past-due UI for Smart Retries — clearer in-app messaging when a payment retry is in flight - Live Stripe CLI webhook integration tests in CI for billing reliability - Synchronous Stripe checkout confirmation before John Deere OAuth redirect (smoother trial start) ### Fixed - Force login prompt on John Deere OAuth — prevents accidentally selecting the wrong account - Server-side redirect to John Deere OAuth after Stripe checkout — eliminates race conditions - Header overflow when sidebar is collapsed on medium screens - DAT-003 leap-year math mismatch in farm intelligence date calculations --- ## 2026-04 — Stripe Billing (Wave 1) ### Added - Stripe webhooks, gateway billing gate, billing flows, and dashboard UI - Per-org billing model ($29/org/month) — retired the Free, Developer, Startup, and Enterprise tiers - Admin billing alerts, request deduplication, and retry configuration --- ## 2026-03 — Test Infrastructure ### Added - Playwright E2E test suite with CI workflow - Responsive layout improvements (container queries, skeleton alignment, overflow fixes) # Blog ## FieldView + Deere Side by Side: Building Cross-Provider Agronomic Workflows with FieldMCP URL: https://www.fieldmcp.com/blog/fieldview-deere-side-by-side-building-cross-provider-agronom Date: 2026-04-29 > Most farm data tools pick a side. Here's how to build workflows that pull from both Climate FieldView and John Deere at the same time, without gluing two APIs together yourself. Here's a scenario that comes up constantly in ag software: a grower uses John Deere equipment with Operations Center for planting and harvest, but their agronomist pushes them toward Climate FieldView because of its scouting and imagery features. Now you have operational records in one place and agronomic context in another. Neither platform talks to the other. Your tool has to stitch it together, and doing that usually means building two separate integrations and writing your own merge logic. This post is about a different approach. Instead of treating FieldView and Deere as competing integrations, you can build a single workflow that pulls from both, and then run real analysis on the combined picture. That's the actual unlock here: not just data access, but what you can do with it once it's in one place. ## Why These Two Providers Keep Showing Up Together Climate FieldView has been around since 2006, which puts it among the oldest platforms in the digital ag space. It was built for field-level monitoring: in-season imagery, scouting records, boundary management. John Deere Operations Center grew from the machine side, pulling in equipment telemetry, planting as-applied maps, and harvest data straight off the combine. In practice, a lot of operations run both. The combine is green. The agronomist logs scouting notes in FieldView. The data never crosses the gap unless someone manually exports and re-imports CSV files, which nobody does consistently. The boundary problem makes this worse. The same physical field might exist under slightly different names and geometries in each platform. Leaf's API solves this with boundary merging and canonical field IDs (explained in detail in their [boundary management documentation](https://withleaf.io/en/tutorials/how-leaf-s-api-manages-field-boundaries-across-providers/)). That's the foundation that makes cross-provider queries tractable at all. ## What a Combined Workflow Actually Looks Like Let's say you want to answer a question like: "For fields where we planted late last season, how did harvest yields come out?" That question requires planting dates, harvest yields, and the ability to match them to specific fields. If planting came off the Deere monitor and yield data is in FieldView, you need both. With FieldMCP, you start with a field list and then pull operations. Here's what the Deere side of that looks like: ```json // Step 1: Get your org { "resourceType": "organizations" } // Step 2: List fields in that org { "resourceType": "fields", "orgId": "your-org-id" } // Step 3: Pull planting and harvest records for a specific field { "orgId": "your-org-id", "fieldId": "your-field-id", "operationType": "harvest", "dateRange": { "startDate": "2024-09-01", "endDate": "2024-12-01" } } ``` That last call hits [`deere_search_operations`](https://fieldmcp.com/docs/tools/deere/search-operations) and returns harvest records including yield per acre, moisture at harvest, and crop type. Then you can pull planting records the same way with `operationType: "planting"` to get seeding rate, variety, and planting date. The field overview call ties it together: ```json { "orgId": "your-org-id", "fieldId": "your-field-id", "include": ["details", "boundary", "operations"], "operationsDateRange": { "startDate": "2024-03-01", "endDate": "2024-12-01" } } ``` That's [`deere_get_field_overview`](https://fieldmcp.com/docs/tools/deere/get-field-overview). It returns a `canonicalFieldId` when the field has been synced through Leaf. That ID is what lets you match Deere records to FieldView records for the same physical acres. ## Where the Analysis Layer Comes In Raw operations data tells you what happened. It doesn't tell you why, or what to do next. That's where the intelligence tools matter. Once you have field details and yield history pulled from operations records, you can feed them directly into `intel_diagnose_field`. This is where a cross-provider workflow starts pulling real weight. You're not just displaying data from two platforms: you're running agronomic analysis on the combined picture. ```json { "fieldId": "canonical-field-id-from-leaf", "fieldName": "North Quarter", "crop": "corn", "targetCropYear": 2025, "yieldHistory": [ { "year": 2024, "bushelsPerAcre": 187, "crop": "corn" }, { "year": 2023, "bushelsPerAcre": 201, "crop": "corn" }, { "year": 2022, "bushelsPerAcre": 174, "crop": "soybean" } ], "rotationHistory": { "fieldId": "canonical-field-id-from-leaf", "history": [ { "year": 2024, "crop": "corn", "tillage": "no_till" }, { "year": 2023, "crop": "corn", "tillage": "minimum" }, { "year": 2022, "crop": "soybean", "tillage": "no_till" } ] } } ``` The yield history you pass in comes from what you pulled across both providers. The `canonicalFieldId` keeps it all pointing at the same physical ground. See [the diagnose-field docs](https://fieldmcp.com/docs/tools/intelligence/diagnose-field) for the full input schema and what the diagnostic rules actually evaluate. ## The Part That's Easy to Miss Most developers building ag integrations focus almost entirely on data retrieval. Get the fields. Get the boundaries. Get the operations. That's necessary but it's only half the picture. The interesting work happens when you actually use the data. Planting window decisions, late-season yield drags, back-to-back corn rotations with soft harvest conditions: these are things an agronomist thinks about across a season, across providers, across years. The data to reason about them exists. It's just scattered. A cross-provider setup with Leaf giving you canonical IDs, Deere giving you operational records, and FieldView filling in agronomic context means you can build tools that actually reason at that level. An LLM with access to that data and the right tool schemas can answer questions that used to require someone to manually pull reports from three different browser tabs. That's not marketing. That's just what structured farm data makes possible once the plumbing is in place. The [FieldMCP quickstart](https://fieldmcp.com/docs/quickstart) will get you connected fast if you want to see it working with your own data. The next concrete step: get a Leaf API token, connect your FieldView and Deere accounts, and run a `deere_get_field_overview` call with `include: ["details", "boundary", "operations"]` on one of your fields. Look at the `canonicalFieldId` in the response. That ID is your bridge between providers. Everything else follows from there. ## What Multi-Provider Farm Data Actually Costs You at Query Time URL: https://www.fieldmcp.com/blog/what-multi-provider-farm-data-actually-costs-you-at-query-ti Date: 2026-04-22 > When your field data lives across John Deere, FieldView, Trimble, and Raven, the hidden cost isn't the integration. It's what happens when you try to query across all of it at once. The Farmers Edge and Leaf partnership announcement is worth reading if you haven't already. The short version: Leaf's unified API is now the data backbone connecting FarmCommand to Climate FieldView, Trimble, Raven, Stara, AgLeader, and others. ([Source: Leaf Agriculture blog](https://withleaf.io/en/blog/farmers-edge-leaf-announce-partnership/)) Most of the coverage focuses on what new data becomes available. That's the obvious story. The less obvious one is the query architecture question that partnership announcements like this tend to gloss over: how do you actually read data across all those providers at the right time, without turning every lookup into a multi-second waterfall? That's what this post is about. ## The Fan-Out Problem Nobody Talks About Here's the scenario. A grower has equipment from two manufacturers, fields tracked in FieldView for one farm and Trimble for another, and their agronomist uses a third platform. Totally normal. Data lives in four places. You write a tool that asks: "Which of my corn fields had a harvest operation in the last 60 days?" To answer that, you need to fan out to every provider, ask each one for operations, filter by crop and date, and stitch results together. If each provider call takes 400ms (optimistic, honestly), and you're hitting four of them sequentially, you've burned 1.6 seconds before any logic runs. That's a slow chatbot answer. It's a broken workflow in a field-edge context where someone needs that information on a phone with intermittent signal. The fix isn't just "call them in parallel." Parallel helps, but it doesn't solve the harder problem: you don't know ahead of time which providers have data for which fields. So you call all of them speculatively, most return nothing useful, and you pay the latency cost regardless. This is the thing that unified APIs like Leaf's are quietly solving. Instead of four round trips to four different auth systems, you make one call and get a normalized response. The fan-out still happens, it just happens inside their infrastructure where they can optimize it. ## What This Means for How You Write Queries When you have a single normalized data source, your query patterns can change pretty meaningfully. Before: fetch fields from each provider, deduplicate by boundary match (painful), then search operations per provider. After: fetch fields from the unified layer, get a canonical field ID, search operations once. The canonical ID piece matters more than it sounds. If you've read [the post on the field identity problem](/blog/field-identity-problem), you know that the same physical acre often exists as separate records in John Deere Operations Center, FieldView, and Trimble. A unified API that resolves those into one identifier means your operation searches stop double-counting. Here's what a targeted harvest search looks like against the Deere side of FieldMCP, using the same pattern you'd apply through any normalized data layer: ```json // Search for recent harvest operations across an org { "orgId": "your-org-id", "operationType": "harvest", "dateRange": { "startDate": "2025-08-01", "endDate": "2025-10-31" }, "limit": 50 } ``` That's the input to [`deere_search_operations`](/docs/tools/deere/search-operations). One call, one provider, date-scoped. The design goal is the same whether you're querying Deere directly or going through a unified layer: minimize speculative fetches, scope to what you actually need. ## The Normalization Tax (and When It's Worth Paying) Unified APIs aren't free. The abstraction costs you something. First, you lose provider-specific fields. Trimble might surface something about guidance line accuracy that doesn't exist in FieldView's data model. A unified schema has to pick a lowest common denominator, or ship provider-specific extensions, which defeats part of the purpose. Second, you're dependent on how fresh the normalized data is. If a provider pushes data to the unified layer on a delay, your "current" yield data might be hours old. That's usually fine for historical operations analysis. It's less fine if you're trying to track a combine's progress during active harvest, where John Deere Operations Center updates equipment position every 30 seconds. For real-time equipment tracking, you probably still want a direct connection. For cross-provider field history queries, a normalized layer is almost always the right call. These are different use cases and they deserve different tools. ```json // Direct equipment telemetry: use this for active harvest monitoring { "equipmentId": "your-equipment-id", "orgId": "your-org-id", "include": ["details", "location", "alerts", "engineHours"] } ``` That input goes to [`deere_get_equipment_status`](/docs/tools/deere/get-equipment-status). It's the right tool when you need to know where a combine is right now, not where it was yesterday. Unified API layers are generally not optimized for this kind of telemetry pull. The variable rate technology literature from University of Florida puts it plainly: effective precision ag depends on matching data collection frequency to the decision being made. ([AE607, UF/IFAS](https://ask.ifas.ufl.edu/publication/AE607)) Historical soil sampling, yield maps, and application records tolerate some staleness. Active field equipment does not. ## Building for the Normalized Layer Without Giving Up Precision The practical pattern I'd recommend: use the unified layer for discovery and history, drop down to provider-specific calls for real-time state. Discovery looks like this. You need to know what fields a grower has, across all their providers, without knowing in advance which providers they've connected. A unified API gives you that list with canonical IDs. Then you can use those canonical IDs as stable references across all your subsequent queries. For the field detail pass, you want boundary geometry, active crop, and recent operations in one shot: ```json // Pull field details, boundary, and recent operations together { "orgId": "your-org-id", "fieldId": "canonical-field-id", "include": ["details", "boundary", "operations"], "operationsDateRange": { "startDate": "2024-09-01", "endDate": "2025-04-22" }, "operationsLimit": 20 } ``` That's the input to [`deere_get_field_overview`](/docs/tools/deere/get-field-overview). When the field has been synced across providers, it returns a `canonicalFieldId` you can carry into analysis calls. The boundary plus recent operations in a single response means you're not making three calls where one will do. After you have the field data, analysis is a separate step. Feeding historical operations into `intel_diagnose_field` gives you prioritized action recommendations, but only if the underlying data is complete enough to be meaningful. Garbage in, garbage out, and "garbage" in this context often means "operations data from only two of four providers." This is the real argument for investing in unified API integrations: it's not just about data availability. It's about data completeness, which directly determines whether your agronomic analysis is trustworthy. ## Where to Start If you're building a tool that needs to span multiple ag data providers, the first concrete step is getting authentication set up cleanly. See the [OAuth setup docs](/docs/authentication/oauth) before you write a single query, because provider auth is where most integrations quietly break later. Once that's in place, the [quickstart guide](/docs/quickstart) walks through a full field data pull. The query patterns there generalize well to multi-provider work: discover organizations first, then fields, then operations. That hierarchy holds regardless of how many providers are feeding into your normalized layer. The Farmers Edge and Leaf announcement is a data point about where the industry is heading. Normalization and federation are becoming infrastructure, not competitive advantages. Your job as a developer is to build tools that use that infrastructure well, which means understanding the query cost model underneath it. ## ARC vs. PLC Calculator: How to Estimate 2025 Program-Year Payments by County and MYA Price URL: https://www.fieldmcp.com/blog/arc-vs-plc-calculator-how-to-estimate-2025-program-year-payments Date: 2026-04-21 > How to estimate ARC-CO versus PLC payments for the 2025 program year using county benchmarks, MYA price assumptions, and PLC yield inputs. If you're trying to compare ARC-CO versus PLC for the 2025 program year, you do not need a full farm-management integration stack just to get started. The core comparison is driven by public USDA/FSA program data plus a few farm-specific inputs. That is why we built a free [ARC-CO vs PLC calculator](/arc-plc-calculator) for FieldMCP. It is not a replacement for your advisor or local FSA office. It is a faster way to test scenarios using official county benchmark data and your own yield and price assumptions. ## What the Calculator Actually Uses For the MVP, the calculator focuses on the **2025 program year**, which generally means payments issued after **October 1, 2026**. The comparison uses: - Official FSA ARC-CO county benchmark yields and revenues. - Official FSA ARC-CO benchmark and actual price tables for the 2025 program year. - Your own assumptions for: - county yield - market year average (MYA) price - PLC yield - base acres Importantly, this workflow does **not** require John Deere data. ARC-CO and PLC estimates are driven mainly by public program rules and the assumptions you enter. ## Inputs You Still Need From the Farm Side Even though the public data gets you most of the way there, you still need a few farm-specific values: - **Base acres** for the covered commodity. - **PLC yield** for the farm. - **County yield assumption** for the current scenario. - **MYA price assumption** for the current scenario. The county benchmark itself is public. The farm-specific yield and acreage inputs are not. ## ARC-CO Versus PLC in Plain English ARC-CO is a county-revenue comparison. It starts with a county benchmark revenue, then compares that benchmark against actual county revenue under your current assumptions. PLC is a price-support comparison. It looks at the effective reference price for the crop, compares that against the effective price under your MYA scenario, and then applies your PLC yield and payment-acre factor. That means the two programs react differently: - ARC-CO is more sensitive to county yield outcomes and benchmark revenue. - PLC is more sensitive to price downside and your farm's PLC yield. This is why a simple side-by-side scenario tool can be useful even before you get into more customized planning. ## Why We Focused the MVP on 2025 There are plenty of extension and university tools already online for ARC/PLC comparisons. The opportunity here is not pretending FieldMCP invented the category. The opportunity is building a clean, fast, public-data workflow that fits next to broader ag-data infrastructure. We intentionally started with the current decision-relevant cycle instead of overreaching across too many years at once. The current calculator is anchored to the latest official 2025 program-year FSA workbooks available in April 2026. That matters because the details can change. Some USDA/FSA source files are updated on different dates, and the safest implementation is the one that clearly states which official tables it uses. ## Try the Calculator If you want to run your own scenario, use the free [ARC-CO vs PLC calculator](/arc-plc-calculator). The current MVP is designed to answer a practical question quickly: > Under this county benchmark, this yield assumption, this MYA price assumption, and this farm PLC yield, which program currently looks stronger? That is a small but useful workflow, and it is a good example of the kind of product-adjacent agricultural data tooling FieldMCP can keep building. ## Platform Consolidation in Ag Data: What the Farmers Edge + Leaf Partnership Actually Means for Developers URL: https://www.fieldmcp.com/blog/platform-consolidation-in-ag-data-what-the-farmers-edge-leaf Date: 2026-04-15 > When ag data platforms consolidate through unified APIs, the real winners are developers building cross-provider tools. Here's what that means in practice. The Farmers Edge and Leaf Agriculture [partnership](https://withleaf.io/en/blog/farmers-edge-leaf-announce-partnership/) got a bit of press as a business development announcement. Two companies teaming up, logos in a press release, the usual. But if you read past the marketing layer, there's something more interesting happening. Farmers Edge already had direct integrations with John Deere and Case. Adding Leaf brings in Climate FieldView, Trimble, Raven, Stara, and AgLeader through a single normalized layer. That's a meaningful jump in coverage. The angle worth thinking about isn't the partnership itself. It's what it signals about how ag data infrastructure is maturing, and what that means for developers building on top of it. ## The Aggregator Layer Is Becoming Load-Bearing For a while, the ag data world looked like this: every major equipment and software provider ran their own API, every one of them had slightly different auth patterns, different field models, different operation schemas. If you wanted to build something useful for a farm running mixed equipment (which is most farms), you were writing bespoke integrations for each provider. Leaf's bet was that someone should normalize all of that. One API surface, consistent field and operation objects, unified auth. The Farmers Edge deal is evidence that this layer is becoming infrastructure that serious ag platforms now build on top of, rather than around. This matters for developers because when a platform like Farmers Edge routes provider data through a normalized API instead of maintaining individual integrations, the blast radius of a single provider schema change shrinks dramatically. You stop chasing each equipment OEM's API changelog and start relying on the normalization layer to absorb it. That said, normalization always has a cost. When you flatten provider-specific data into a common schema, you lose some fidelity at the edges. Variable rate prescription details, for example, often have provider-specific fields that don't map cleanly across platforms. Worth understanding what you're trading away before assuming the unified layer covers everything you need. ## What Multi-Provider Data Actually Looks Like in Practice Take a farm that runs John Deere equipment but uses Climate FieldView for field records and Trimble for application data. From a data standpoint, this is a genuinely common situation. The same physical field has records scattered across three systems, often with slightly different boundaries, different field names, and different operation schemas. When you're building tools that need to reason about that field, the first problem is identity. Which records actually belong to the same acre? The second problem is schema. Harvest data from Deere and harvest data from Trimble don't look the same coming out of their respective APIs. Here's what a multi-step query looks like when you're pulling field and operation data through FieldMCP: ```json // Step 1: Discover orgs { "resourceType": "organizations" } // Step 2: List fields for your org { "resourceType": "fields", "orgId": "your-org-id" } // Step 3: Pull field details, boundary, and recent operations { "orgId": "your-org-id", "fieldId": "your-field-id", "include": ["details", "boundary", "operations"], "operationsDateRange": { "startDate": "2024-09-01", "endDate": "2025-01-01" } } // Step 4: Search specifically for harvest operations if you want more { "orgId": "your-org-id", "fieldId": "your-field-id", "operationType": "harvest", "dateRange": { "startDate": "2024-09-01", "endDate": "2025-01-01" } } ``` The `canonicalFieldId` you get back from `deere_get_field_overview` is your stable cross-provider reference. That's the thing worth storing. Provider-specific IDs shift; the canonical ID is meant to be durable across syncs. See the [get-field-overview docs](https://fieldmcp.com/docs/tools/deere/get-field-overview) for details on how that works. ## The Variable Rate Angle Nobody Talks About Deals like the Farmers Edge/Leaf partnership get framed around "data access." More fields, more operations, more coverage. That framing is correct but incomplete. The more interesting downstream effect is what unified operation data enables for variable rate decision-making. Variable rate technology (VRT) for inputs like seed and fertilizer depends on having consistent historical data across the field: yield history, soil test results, application records. When those records live in three different systems with three different schemas, building a coherent picture of field variability is a data wrangling problem before it's an agronomy problem. When that data is normalized, you can actually run analysis. Feed yield history, soil tests, and rotation data into a diagnostic tool and get back something actionable. The [University of Florida Extension's VRT overview](https://ask.ifas.ufl.edu/publication/AE607) has a solid breakdown of the data inputs that drive good variable rate prescriptions. The short version: you need consistent spatial data over multiple years. That's exactly what multi-provider normalization makes easier to assemble. With FieldMCP's `intel_diagnose_field`, you can pipe normalized field data directly into agronomic analysis: ```json { "fieldId": "canonical-field-uuid", "fieldName": "North Field", "acres": 180, "crop": "corn", "targetCropYear": 2025, "location": { "state": "IL", "region": "central" }, "yieldHistory": [ { "year": 2022, "bushelsPerAcre": 198, "crop": "corn" }, { "year": 2023, "bushelsPerAcre": 172, "crop": "soybean" }, { "year": 2024, "bushelsPerAcre": 205, "crop": "corn" } ], "rotationHistory": { "fieldId": "canonical-field-uuid", "history": [ { "year": 2022, "crop": "corn", "tillage": "no_till" }, { "year": 2023, "crop": "soybean", "tillage": "no_till" }, { "year": 2024, "crop": "corn", "tillage": "minimum" } ] } } ``` That only works if you actually have the yield history across years. Which requires consistent data collection across providers. Which is exactly the problem the Farmers Edge/Leaf integration is trying to solve. See the [diagnose-field tool docs](https://fieldmcp.com/docs/tools/intelligence/diagnose-field) for the full input schema and what you get back. ## The Security Question Nobody Wants to Ask Consolidating farm data through fewer API layers has real benefits. It also concentrates risk. When researchers have found vulnerabilities in individual ag platform APIs (and [they have](https://www.vice.com/en/article/z3xkdy/hackers-uncover-weaknesses-in-agriculture-giants-systems)), a normalization layer sitting on top of multiple providers represents a broader attack surface. This isn't an argument against aggregation. It's an argument for treating auth seriously at every layer. If you're building tools on top of any ag data API, understand how tokens are scoped, how refresh flows work, and what a compromised credential can actually access. Our [OAuth authentication docs](https://fieldmcp.com/docs/authentication/oauth) cover how FieldMCP handles this. Read the equivalent docs for every provider you touch. Farmers Edge routing data through Leaf doesn't inherently make this better or worse. But if you're building on top of that stack, you need to know where the auth boundaries actually sit. ## What to Do With This The Farmers Edge/Leaf deal is useful as a signal: the ag data industry is consolidating around normalization layers, and that's making it more practical to build tools that work across the full diversity of equipment and software on real farms. If you're building ag software and you're still managing individual provider integrations by hand, now is a good time to reconsider that architecture. If you're already on a normalized layer, start thinking harder about what multi-year, multi-provider data unlocks for analysis, not just what it unlocks for display. Start with the [FieldMCP quickstart](https://fieldmcp.com/docs/quickstart) to see how multi-provider field data comes together in practice. If you already have John Deere connected, try running `deere_search_operations` across a full growing season and see what you can actually build when the data retrieval problem is solved. ## The Field Identity Problem: Why the Same Acre Has Three Different Names URL: https://www.fieldmcp.com/blog/the-field-identity-problem-why-the-same-acre-has-three-diffe Date: 2026-03-20 > How Leaf's boundary merging works under the hood, what a canonicalFieldId actually means, and why it matters when you're building tools that span John Deere, FieldView, and Trimble. Here's a problem that doesn't show up in any marketing material but will absolutely break your application in year two: the same physical field exists as three separate records across three different platforms, with three different names, three slightly different boundary polygons, and no shared identifier between them. This isn't a hypothetical. It's what happens when a farmer uses John Deere Operations Center for guidance and machine data, Climate FieldView for scouting, and Trimble for application records. Each platform got its boundary drawn a different way. Maybe one was drawn by hand on a tablet. Maybe another was auto-detected from machine data. The acreage doesn't match exactly. The field name is "Home 40" in one system and "Home Farm NE" in another. If you're building anything that aggregates data across providers, this will be your problem to solve. Leaf's API takes a real swing at it. I want to explain how it actually works, and then show you where FieldMCP fits into that picture. ## Why Field Boundaries Are Messier Than They Look A field boundary is a polygon. Polygons are math. Math should be consistent. The problem is that the polygon gets drawn by humans (or by automated detection algorithms trained on machine path data), and those processes don't agree on where a field edge is, especially on irregular ground. Consider what happens at the corners. One operator drives to the fence line. Another doesn't. The auto-detected boundary from planter path data clips the headland differently than the hand-drawn polygon in FieldView. You end up with two polygons representing the same physical acre that overlap by 94% but are technically different geometries. Now multiply that by the number of fields on a real operation. My uncle farms around 1,400 acres across a dozen landlords. Some fields have been in three different software systems over the past decade. The geometry drift accumulates. This is not a solved problem in precision agriculture, which is something the [IEEE article on the history of precision ag](https://spectrum.ieee.org/tech-history/silicon-revolution/john-deere-and-the-birth-of-precision-agriculture) doesn't fully reckon with, but it's the reality anyone building in this space runs into fast. ## What Leaf Actually Does With Those Polygons Leaf's approach is documented in [their tutorial on field boundary management](https://withleaf.io/en/tutorials/how-leaf-s-api-manages-field-boundaries-across-providers/), but I'll give you my read on the mechanics. Leaf takes the field geometry, the field name, and the season from each connected provider. It then runs a matching process to determine whether two records from different providers are probably the same physical field. The matching uses geometric overlap, not exact equality. Two polygons don't need to be identical. They need to overlap enough to be reasonably interpreted as the same location. When Leaf decides they match, it creates a Merged Field. That Merged Field gets a stable ID that doesn't change when the underlying provider records change. That ID is your anchor. This matters for a few reasons. First, you can query operations data from John Deere and yield data from FieldView and join them on a single field reference. Second, when a farmer updates their boundary in one platform, your application doesn't have to re-discover the field. Third, when you're building something that persists data about a field (recommendations, notes, historical analysis), you have a stable key to store it against. The geometry matching isn't magic. It will miss fields that have genuinely different footprints due to boundary renegotiation or land parcel changes. But for the common case, where the same physical field got drawn slightly differently in two apps, it works. ## The canonicalFieldId and How It Shows Up in FieldMCP When you call `deere_get_field_overview` through FieldMCP, the response includes a `canonicalFieldId` when the field has been synced and matched. This is a UUID that corresponds to the merged identity across providers. Here's the call: ```json { "orgId": "your-org-id", "fieldId": "deere-field-id", "include": ["details", "boundary", "operations"] } ``` The `canonicalFieldId` in the response is the field's stable cross-provider identity. You can read more about the full parameter set at [/docs/tools/deere/get-field-overview](https://fieldmcp.com/docs/tools/deere/get-field-overview). If you're building a feature that stores agronomic recommendations per field, store them against the `canonicalFieldId`, not the provider-native field ID. The provider ID can change. The provider might change. The canonical ID is the thing that survives both. Here's a pattern that makes sense for cross-provider field work: ```json // Step 1: Discover fields in the org { "resourceType": "fields", "orgId": "your-org-id" } // Step 2: Get full details including boundary and operations for a field { "orgId": "your-org-id", "fieldId": "deere-field-id", "include": ["details", "boundary", "operations"], "operationsDateRange": { "startDate": "2024-01-01", "endDate": "2025-01-01" } } // The response includes canonicalFieldId — store this. // Use it as your stable key when joining data from other providers. ``` See [/docs/tools/deere/list-resources](https://fieldmcp.com/docs/tools/deere/list-resources) for the full options on resource discovery. ## What This Actually Enables (and What It Doesn't) When the field identity problem is solved, a class of applications becomes possible that simply wasn't viable before. You can build a planting-to-harvest traceability view that spans providers. Planting data from John Deere, application records from Trimble, harvest from FieldView, all joined on the same field identity. You can run multi-year yield analysis without manually reconciling which records belong to which field. You can hand a canonical field ID to an agronomic analysis tool and trust that the history it sees is complete. The thing this doesn't solve: data quality within a single provider. If a planting record in John Deere Operations Center has a wrong seeding rate because the operator didn't set the controller correctly, Leaf's field merging doesn't fix that. The record is accurate to what the machine reported. Garbage in, garbage out. Field identity normalization is a prerequisite for good analysis. It's not a substitute for clean data. The other thing to know: the merge isn't instantaneous. Leaf syncs on a schedule. If a farmer just added a field in FieldView this morning, it may not be merged yet. Build your application to handle the case where a `canonicalFieldId` isn't present yet on a given field record. ## Start With a Real Field, Not a Demo Account The fastest way to see this in practice is to connect a real provider account and pull actual field data. If you have a John Deere Operations Center account with a few fields, the [FieldMCP quickstart at /docs/quickstart](https://fieldmcp.com/docs/quickstart) will get you reading field records in under ten minutes. Once you have a field with a `canonicalFieldId`, try querying operations across a date range using `deere_search_operations`: ```json { "orgId": "your-org-id", "operationType": "harvest", "dateRange": { "startDate": "2023-09-01", "endDate": "2023-12-01" }, "limit": 50 } ``` Then look at what you get back. If you're running a multi-provider setup, check whether the same field shows up with consistent identity across providers. That's the thing to verify before you build anything on top of it. The field identity layer is boring infrastructure. But boring infrastructure is what makes everything else possible. Get it right before you build the interesting parts on top. ## AI in Precision Agriculture: What Developers Actually Need to Build URL: https://www.fieldmcp.com/blog/ai-in-precision-agriculture-what-developers-actually-need-to Date: 2026-03-14 > A staff engineer's take on where AI in farm software is headed, why the data plumbing problem still matters, and how to build tools that hold up in the field. Most "AI in agriculture" content is written by people who have never watched a combine header plug with wet corn stalks at 11pm in October. I have. The gap between what gets written and what farmers actually need is wide. But something real is happening right now, and if you build farm software, you need to understand it. The key insight is this: LLMs are only as useful as the data you feed them. In agriculture, that data has been trapped in silos for 30 years. The work of getting it out is boring and unglamorous and absolutely foundational. Developers who figure out that plumbing first will build things that matter. The rest will ship dashboards nobody opens. ## The Data Problem Is Still the Real Problem Precision agriculture has been generating data since the mid-90s. GPS yield monitors, variable rate controllers, soil EC maps. The [IEEE documented John Deere's early GPS work](https://spectrum.ieee.org/tech-history/silicon-revolution/john-deere-and-the-birth-of-precision-agriculture) going back decades. The data was never the issue. The issue is that it lives in formats and platforms that don't talk to each other. A grower running a mixed-equipment operation might have yield data in the John Deere Operations Center, soil tests in a PDF from a county co-op lab, planting records on an SMS file from five years ago, and prescription maps from an agronomist's desktop software. No single tool sees all of it. So when you try to build something that answers the question "why did this field underperform last year," you're already fighting against the data model before you write a single prompt. Leaf's approach to this is worth understanding. They match field geometry across platforms and assign a stable merged field ID, so the same physical field doesn't appear as three different records depending on which app created it. [Their docs on cross-provider boundary management](https://withleaf.io/en/tutorials/how-leaf-s-api-manages-field-boundaries-across-providers/) explain the geometry matching logic. It's not glamorous, but a stable canonical field ID is what makes any downstream AI analysis actually coherent. ## What Structured Farm Data + LLMs Can Actually Do Here's where I get genuinely excited, and I want to be specific because vague enthusiasm is useless. When you have clean, structured field data piped into an LLM in the right shape, a few things become possible that weren't before. You can explain agronomic decisions in plain language, not just show a number. You can chain observations across time (yield history, rotation, soil test) and surface patterns a grower wouldn't spot manually. You can generate a field-level action plan that accounts for financial constraints, tenure, and risk tolerance. None of that requires magic. It requires good inputs. Here's what a two-step workflow looks like in practice. First, pull the field data: ```json { "orgId": "459201", "fieldId": "field-88b2c4", "include": ["details", "boundary", "operations"], "operationsDateRange": { "startDate": "2023-01-01", "endDate": "2025-12-31" }, "operationsLimit": 20 } ``` That goes to [`deere_get_field_overview`](/docs/tools/deere/get-field-overview), which returns field details, the GeoJSON boundary, and recent planting/harvest/application records. Then you take what you got and pass it to the diagnostic engine: ```json { "fieldId": "field-88b2c4", "fieldName": "South 40", "acres": 38.4, "crop": "corn", "targetCropYear": 2026, "location": { "state": "IL", "region": "central" }, "yieldHistory": [ { "year": 2024, "bushelsPerAcre": 187, "crop": "corn" }, { "year": 2023, "bushelsPerAcre": 201, "crop": "corn" }, { "year": 2022, "bushelsPerAcre": 164, "crop": "soybean" } ], "rotationHistory": { "fieldId": "field-88b2c4", "history": [ { "year": 2024, "crop": "corn", "tillage": "no_till" }, { "year": 2023, "crop": "corn", "tillage": "no_till" }, { "year": 2022, "crop": "soybean", "tillage": "minimum" } ] }, "tenure": { "type": "cash_rent", "leaseYearsRemaining": 2 } } ``` That goes to [`intel_diagnose_field`](/docs/tools/intelligence/diagnose-field). What comes back is a prioritized action plan, not a pile of raw numbers. The system knows to weight recommendations differently when a grower has two years left on a cash rent lease versus owning the ground. That context matters enormously and most precision ag tools ignore it completely. ## Security and Access: Don't Ignore This I want to be direct about something. Connecting to John Deere's Operations Center means you're handling credentials that control real equipment. In 2021, researchers found meaningful vulnerabilities in agtech systems including John Deere infrastructure. The [Vice coverage of that disclosure](https://www.vice.com/en/article/z3xkdy/hackers-uncover-weaknesses-in-agriculture-giants-systems) was uncomfortable reading for everyone in this industry. The practical implication for developers is simple: use OAuth, don't store API tokens in ways that expose them, and understand what permissions you're actually requesting. If your app only needs to read field boundaries and yield history, don't request write access to machine controls. Scope your tokens narrowly. See the [OAuth setup guide](/docs/authentication/oauth) before you write your first integration call. This is not a theoretical risk. Farmers trust you with data that represents their livelihood. Treat it accordingly. ## What the "AI Agriculture" Wave Gets Wrong A lot of what's being marketed right now is a thin LLM wrapper around the same old data problems. The AI isn't wrong, the inputs are. You can't generate a useful nitrogen recommendation from bad or incomplete soil test data. You can't explain a yield drag if you don't have accurate boundary geometry to tie the yield monitor data to the right field. I've seen startups spend six months on a "conversational agronomist" interface and two weeks on data ingestion. That's backwards. The interface is the easy part. Getting a corn farmer's 2019 planting records out of an old Climate Corp account and into a format that a diagnostic tool can actually use, that's the hard part. The developers I've seen do this well start with the data model. They get canonical field IDs stable. They normalize operation records across equipment brands. They handle the boundary mismatch problem instead of ignoring it. Then they build the AI layer on top of a foundation that holds. If you're starting out, the [FieldMCP quickstart](/docs/quickstart) walks through the basic connection flow. Once you have fields loading correctly, [`deere_search_operations`](/docs/tools/deere/search-operations) is the right next tool to learn. It lets you pull planting and harvest records across an entire org with date filters, which is usually the first thing you need to build any kind of historical analysis. The path forward for farm software isn't more AI marketing. It's better plumbing, applied to real agronomic questions, shipped to people who plant in May and harvest in October and don't have time for tools that don't work. Start there. ## How to Access Climate FieldView Data Through Leaf's Unified API URL: https://www.fieldmcp.com/blog/how-to-access-climate-fieldview-data-through-leaf-s-unified- Date: 2026-03-10 > A practical guide to pulling Climate FieldView field data, operations, and boundaries through Leaf's unified agriculture API, with real code examples. Here's the problem I run into constantly when building agtech tools: a farmer uses FieldView on their tablet, their agronomist pulls data from a different platform, and the lender wants a report in yet another format. The data exists. It's just scattered across silos that weren't designed to talk to each other. Leaf Agriculture's unified API is the most honest attempt I've seen to fix this. It normalizes field boundaries, operations, and farmer data across providers, including Climate FieldView, into a single schema. You authenticate once, query one API, and get consistent field records regardless of where the grower originally uploaded their data. This post is about how that actually works. Not the marketing version. The plumbing version. ## What Leaf Does (and Why It Matters for FieldView Specifically) Climate FieldView has a massive install base in corn and soy country. My uncle runs FieldView on his S780 and has years of planting and harvest files sitting in there. That data is genuinely valuable, but getting it out programmatically has historically required navigating FieldView's own API, which has its own auth flow, its own field ID scheme, and its own response shape. Leaf normalizes all of that. When you connect a grower's FieldView account through Leaf, their fields come back with a stable merged field ID that Leaf maintains across providers. If the same field exists in FieldView and in John Deere Operations Center, Leaf matches the geometry and gives you one record. [Leaf's docs on boundary merging](https://withleaf.io/en/tutorials/how-leaf-s-api-manages-field-boundaries-across-providers/) explain the geometry matching logic in detail. It's worth reading if you're building anything that touches multi-provider farms. The merged field ID is the part that actually makes this useful at scale. Your app doesn't have to care whether a farmer switched from FieldView to MyJohnDeere last season. The field ID stays stable. ## Authentication: Get This Right First Every Leaf API call requires a bearer token. You get it by authenticating with Leaf's OAuth endpoint using your API credentials. Don't skip reading the [authentication docs](/docs/authentication/oauth) before you write a single data fetch. Once you have a token, all FieldView data flows through the same Leaf endpoints as any other provider. There's no FieldView-specific SDK to install. That's the point. One thing I'll flag: make sure the grower has completed the OAuth consent flow for their FieldView account inside your app. Leaf can't pull their data until that connection is authorized. This trips up a lot of integrations early on. Build the consent UI before you build the data pipeline. ## Fetching Field Data Through the API After auth is sorted, the pattern for FieldView data is the same as any provider in Leaf's system. You list fields for an organization, then fetch the details you need for each field. Here's what that looks like when you're working through FieldMCP's tool layer (which wraps Leaf and other providers into MCP-compatible tools): List fields for an org first: ```json { "resourceType": "fields", "orgId": "your-leaf-org-id" } ``` That gives you a list of fields. Then for any field you want to dig into, pull the full overview: ```json { "orgId": "your-leaf-org-id", "fieldId": "field-uuid-from-list", "include": ["details", "boundary", "operations"], "operationsDateRange": { "startDate": "2024-01-01", "endDate": "2025-01-01" }, "operationsLimit": 20 } ``` This returns the field name, acreage, active crop, GeoJSON boundary, and recent operations in one call. See the [get-field-overview docs](/docs/tools/deere/get-field-overview) for the full include options. For FieldView farms specifically, the operations data is often the richest part. Planting populations, harvest moisture, application records. All of it flows through the same `operations` include. No separate endpoint. ## Querying Operations Across a FieldView Farm If you want to search operations across multiple fields, use a search call scoped to the org: ```json { "orgId": "your-leaf-org-id", "operationType": "harvest", "dateRange": { "startDate": "2024-09-01", "endDate": "2024-11-30" }, "limit": 50 } ``` This is useful during or after harvest when you want to pull yield data across an operation without knowing specific field IDs upfront. October in central Illinois, you're not sitting at a desk. You need queries that work fast with minimal setup. See [search-operations](/docs/tools/deere/search-operations) for the full parameter list. Planting operations work the same way. Set `operationType` to `"planting"` and a spring date range, and you'll get variety, seeding rate, and population data back for every field that was planted through FieldView. ## What to Do With the Data Once You Have It Raw field records are only useful if you do something with them. The combination of Leaf-normalized FieldView data plus an intelligence layer is where things get interesting. After pulling harvest operations for a field, you have everything you need to run a yield diagnosis. Pass the yield history, crop type, and field ID into an analysis tool: ```json { "fieldId": "canonical-field-uuid", "fieldName": "Home Farm North", "crop": "corn", "targetCropYear": 2025, "location": { "state": "IL", "region": "central" }, "yieldHistory": [ { "year": 2024, "bushelsPerAcre": 187, "crop": "corn" }, { "year": 2023, "bushelsPerAcre": 201, "crop": "corn" }, { "year": 2022, "bushelsPerAcre": 165, "crop": "corn" } ] } ``` That feeds into [intel_diagnose_field](/docs/tools/intelligence/diagnose-field), which returns triggered diagnostic rules, confidence levels, and a prioritized action plan. The 2022 yield dip in that example would likely flag a drought or compaction pattern depending on what other data you've included. This is the combination that I think actually delivers value: Leaf handles the normalization, you focus on the analysis. Most "AI-powered agriculture" tools I've seen skip the normalization step and then wonder why their models produce garbage. Garbage in, garbage out. Always. ## Start Here If you're building on FieldView data and haven't looked at Leaf's unified API yet, start with the [FieldMCP quickstart](/docs/quickstart). It walks you through connecting a provider, authenticating, and making your first field query in under 30 minutes. The auth setup takes the longest. Once that's done, the field data queries are fast and the response shapes are consistent. That consistency is what makes it worth the upfront investment. Get the OAuth flow working first. Everything else follows from there. ## Getting Started with John Deere Field Data Using FieldMCP URL: https://www.fieldmcp.com/blog/getting-started-with-john-deere-field-data-using-fieldmcp Date: 2026-03-06 > A step-by-step tutorial for connecting your John Deere Operations Center account to FieldMCP and pulling real field data in minutes. John Deere has been collecting precision agriculture data since the late 1990s. Your operation probably has years of planting records, yield maps, and application data sitting in Operations Center right now. Getting that data out and into something useful has always been the hard part. FieldMCP makes the plumbing straightforward. You authenticate once, and then you can query fields, boundaries, operations, and equipment through a clean set of MCP tools. This tutorial walks you through the whole thing: auth setup, discovering your org, pulling field data, and running your first field analysis. If you want to skip ahead and read the full reference, the [FieldMCP docs](/docs) have you covered. Otherwise, let's go step by step. ## Step 1: Authenticate with John Deere John Deere uses OAuth 2.0 to protect Operations Center data. This is the right call from a security standpoint (there have been well-documented concerns about agricultural data security, and [researchers have found real vulnerabilities at agtech companies](https://www.vice.com/en/article/z3xkdy/hackers-uncover-weaknesses-in-agriculture-giants-systems)). It does mean you need to complete an OAuth flow before anything else works. Follow the [FieldMCP OAuth setup guide](/docs/authentication/oauth) to get your credentials configured. The short version: you register a FieldMCP connection in John Deere's developer portal, complete the authorization flow, and FieldMCP stores your tokens. You do this once. One thing I'd flag early: make sure the Operations Center account you're authorizing actually has access to the fields you want. If a co-op or agronomist manages some of those fields under a separate org, you may need to authorize that org separately. This trips people up. ## Step 2: Discover Your Organization Once auth is done, the first thing to do is find your organization ID. Everything in the Deere API hangs off an org. Fields, equipment, operations, all of it. You need the org ID before you can query anything else. Use `deere_list_resources` with `resourceType: "organizations"`: ```json { "resourceType": "organizations" } ``` This returns your available orgs. If you manage multiple operations (say, your own ground plus some custom work), you'll see them all listed here. Grab the org ID you want to work with. You'll use it in every subsequent call. See the full reference at [/docs/tools/deere/list-resources](/docs/tools/deere/list-resources). ## Step 3: List Your Fields and Pull Field Details With your org ID in hand, list your fields: ```json { "resourceType": "fields", "orgId": "YOUR_ORG_ID" } ``` You'll get back your field names and IDs. If you have a lot of fields, use `limit` and `offset` to page through them. You can also filter by field name if you already know what you're looking for: ```json { "resourceType": "fields", "orgId": "YOUR_ORG_ID", "filters": { "fieldName": "Home Place" } } ``` Once you have a field ID, `deere_get_field_overview` is the tool you'll use most. It pulls field details, boundary geometry, and recent operations in a single call. No need to chain five separate requests. ```json { "orgId": "YOUR_ORG_ID", "fieldId": "YOUR_FIELD_ID", "include": ["details", "boundary", "operations"], "operationsDateRange": { "startDate": "2023-01-01", "endDate": "2025-12-31" }, "operationsLimit": 20 } ``` // Returns field name, acres, active crop, GeoJSON polygon boundary, and recent operations The `canonicalFieldId` in the response is worth paying attention to. It's a stable UUID that stays consistent even if the same field shows up under a different provider. Leaf's API does something similar with their merged field approach, and [that cross-provider matching problem is real](https://withleaf.io/en/tutorials/how-leaf-s-api-manages-field-boundaries-across-providers/). FieldMCP handles it the same way: one stable ID across sources. Full docs at [/docs/tools/deere/get-field-overview](/docs/tools/deere/get-field-overview). ## Step 4: Search Operations Across Your Org Field-level operations are useful. But sometimes you want to ask a broader question: what did I plant across the whole operation this spring, or how did harvest yields look last fall across all my ground? `deere_search_operations` handles that: ```json { "orgId": "YOUR_ORG_ID", "operationType": "harvest", "dateRange": { "startDate": "2024-09-01", "endDate": "2024-12-01" }, "limit": 50 } ``` You can also scope it to a single field: ```json { "orgId": "YOUR_ORG_ID", "fieldId": "YOUR_FIELD_ID", "operationType": "planting", "dateRange": { "startDate": "2024-04-01", "endDate": "2024-06-15" } } ``` For harvest records, you'll get yield per acre, moisture, and total yield. For planting, you get variety, seeding rate, and population. This is the data that's been sitting in your GreenStar displays and monitors for years. It's finally queryable without clicking through Operations Center screens. One practical note: if your planting window data looks sparse, check whether your older displays were uploading automatically or whether someone had to manually sync them. A lot of operations have gaps in 2019 and earlier for exactly that reason. Full reference at [/docs/tools/deere/search-operations](/docs/tools/deere/search-operations). ## Step 5: Run a Field Diagnosis This is where it gets interesting. Once you have field data, you can feed it directly into `intel_diagnose_field` for agronomic analysis. The minimum you need is a field ID, crop, and target year. The analysis gets substantially better with yield history and soil test data, so pull those from your operations records first. ```json { "fieldId": "YOUR_CANONICAL_FIELD_ID", "fieldName": "Home Place North", "acres": 87.4, "crop": "corn", "targetCropYear": 2026, "location": { "state": "IL", "region": "central" }, "yieldHistory": [ { "year": 2022, "bushelsPerAcre": 198, "crop": "corn" }, { "year": 2023, "bushelsPerAcre": 204, "crop": "corn" }, { "year": 2024, "bushelsPerAcre": 187, "crop": "corn" } ] } ``` The tool returns a primary action recommendation, a prioritized action plan, and all triggered diagnostic rules with supporting evidence. If 2024 yield dropped like it did in the example above, the diagnosis will flag that and give you something to investigate. It won't just say "yields were lower." It'll tell you what data supports which hypothesis. You can extend the analysis with soil test data, compaction readings, rotation history, and more. See the full schema at [/docs/tools/intelligence/diagnose-field](/docs/tools/intelligence/diagnose-field). ## Where to Go Next At this point you have the core workflow: authenticate, discover your org, pull field data, search operations, run analysis. That's enough to build something genuinely useful. A few directions worth exploring from here. If you have equipment running in the field, check out [deere_get_equipment_status](/docs/tools/deere/get-equipment-status) for location, alerts, and engine hours. If you want to compare performance across multiple fields, [intel_compare_fields](/docs/tools/intelligence/compare-fields) is the right tool. And if you want to go deeper on what the diagnostic rules actually mean, [intel_get_rule_details](/docs/tools/intelligence/get-rule-details) will explain the agronomic reasoning behind any flagged rule. Start with the [quickstart guide](/docs/quickstart) if you haven't already. It gets you to your first successful tool call in under ten minutes. ## What Is MCP and Why It Matters for Agricultural Data URL: https://www.fieldmcp.com/blog/what-is-mcp-and-why-it-matters-for-agricultural-data Date: 2026-03-03 > A practical explanation of the Model Context Protocol and why it's the missing plumbing between farm data systems and AI assistants. Farm data has a plumbing problem. Equipment data lives in John Deere Operations Center. Boundaries live in one system, soil tests in another, application records somewhere else. You've probably got four logins just to understand what happened on a single field last season. LLMs can reason over farm data in genuinely useful ways. But they can't do that if they can't reach the data. MCP, the Model Context Protocol, is what fixes that. It's a standard that lets AI models call external tools in a structured, predictable way. Think of it as a universal adapter between "things an AI can ask for" and "things your systems actually know." This isn't marketing. It's plumbing. And good plumbing is the whole game. ## What MCP Actually Is MCP is an open protocol, originally developed by Anthropic, that defines how an AI model requests information from external systems and how those systems respond. Before MCP, every team building an AI assistant on top of farm data had to invent their own function-calling conventions. The result was a mess of one-off integrations that broke when APIs changed and couldn't be reused. With MCP, there's a shared contract. A tool has a name, a defined set of inputs, and a description the model can read. The model decides when to call it and what to pass. The server handles the actual data fetch and returns something structured. For agricultural data specifically, this matters because the query surfaces are complex. A question like "which of my fields underperformed county average last harvest?" requires pulling field boundaries, operation records, and external yield benchmarks. That's three different calls, maybe three different APIs. MCP lets you chain those calls without writing a custom orchestration layer for every new question. ## Why Agricultural Data Is Particularly Hard Precision agriculture has been generating data since GPS auto-steer became standard in the late 1990s. (IEEE Spectrum has a good piece on that history [here](https://spectrum.ieee.org/tech-history/silicon-revolution/john-deere-and-the-birth-of-precision-agriculture).) Thirty years of operational data, spread across proprietary platforms that were never designed to talk to each other. The field boundary problem alone is nasty. Leaf's API does interesting work on this: they match field geometry across applications and assign a stable Merged Field ID so the same physical field has a consistent identifier regardless of which platform you're looking at it from ([see how they handle it](https://withleaf.io/en/tutorials/how-leaf-s-api-manages-field-boundaries-across-providers/)). That kind of canonical identity is exactly what you need before you can do anything useful with AI. FieldMCP handles this too. When you call `deere_get_field_overview`, you get back a `canonicalFieldId`, a stable UUID that persists across syncs. That's what lets you reference the same field reliably when you're chaining tools. There's also a security dimension worth taking seriously. Researchers have documented real vulnerabilities in major agtech platforms before, and the attack surface for farm management systems is larger than most people think. A well-designed MCP implementation keeps credentials server-side and controls exactly what data the model can access. Our [OAuth documentation](/docs/authentication/oauth) covers how FieldMCP handles this. ## What a Real MCP Workflow Looks Like Here's a concrete example. Say you want to review planting and harvest data for a specific field to decide whether it's a candidate for a rotation change next year. First, discover your organization and fields: ```json // Step 1: list your orgs { "resourceType": "organizations" } // Step 2: list fields in your org { "resourceType": "fields", "orgId": "123456" } ``` Then pull a full field overview, including recent operations: ```json { "orgId": "123456", "fieldId": "abc789", "include": ["details", "boundary", "operations"], "operationsDateRange": { "startDate": "2023-01-01", "endDate": "2025-12-31" } } ``` That single call returns field details, the GeoJSON boundary, and recent planting/harvest/application records. See the [full tool reference here](/docs/tools/deere/get-field-overview). If you want to search across all fields in the org for harvest data from last fall specifically: ```json { "orgId": "123456", "operationType": "harvest", "dateRange": { "startDate": "2025-09-01", "endDate": "2025-11-30" }, "limit": 50 } ``` Full docs for that tool are at [/docs/tools/deere/search-operations](/docs/tools/deere/search-operations). Once you have field and operations data back, you can pass it directly to `intel_diagnose_field` for agronomic analysis. The tool takes yield history, soil test results, rotation history, and more. It returns a prioritized action plan with confidence levels. No custom prompt engineering required on your end. ## The Gap MCP Closes The honest reason most "AI for agriculture" products don't work is not that the models are bad. The models are fine. The reason they don't work is that the data never reaches the model in a clean, queryable form. Someone asks "should I sidedress this field?" and the AI either hallucinates an answer or returns a generic non-answer because it has no idea what the soil test says, what was planted, or what the yield trend looks like. MCP closes that gap. The model can call `deere_get_field_overview`, get the actual boundary and operations data, call `intel_diagnose_field` with that data, and return a recommendation grounded in the real agronomic record for that specific field. My uncle's operation in central Illinois runs about 1,800 acres across maybe 40 fields. Every one of those fields has a different drainage history, a different compaction situation, a different yield trend. Generic advice is worth nothing. Field-specific, data-grounded advice is worth a lot. That's what structured farm data plus a real tool protocol can actually do. ## Where to Start If you're a developer building on farm data, the fastest path is the [quickstart guide](/docs/quickstart). It walks through authentication, your first tool call against a John Deere organization, and how to chain tools together. If you're evaluating FieldMCP for an existing product, start with the [full docs index](/docs) to understand what's available across the Deere, intelligence, and weather tool namespaces. The plumbing is there. Go build something that actually helps farmers make decisions. # Glossary ## Agronomic Intelligence URL: https://www.fieldmcp.com/glossary/agronomic-intelligence > Data-driven analysis that combines field data, agronomic science, and algorithms to generate actionable farming recommendations. Agronomic intelligence is the application of data analysis and domain-specific agronomic knowledge to generate actionable recommendations for crop production. It sits at the intersection of agricultural science and software engineering — transforming raw field data (yield maps, soil tests, imagery) into decisions about what to plant, how much to fertilize, and when to spray. ## How FieldMCP Implements Agronomic Intelligence FieldMCP's farm-intelligence package provides a rule-based analysis engine that evaluates field data against peer-reviewed agronomic thresholds. Each rule has a unique identifier (e.g., `YLD-001`, `SED-001`, `NUT-001`) and traces back to a specification document that defines the exact logic and thresholds. Every analysis function returns a `RuleResult` that includes: - **Data** — The actual recommendation or analysis output - **Triggered rules** — Which agronomic rules fired, with evidence explaining why - **Data quality** — Whether the input data was complete, partial, or insufficient - **Missing data** — What data gaps exist and how they impact the recommendation This traceability is critical. When an AI application tells a farmer to increase seeding rate in a specific zone, the farmer needs to understand why. The rule ID and evidence chain provide that explanation. ## What Agronomic Intelligence Covers - **Seeding rate optimization** — Recommending plant populations based on [yield history](/glossary/yield-mapping), [soil capacity](/glossary/soil-sampling), and hybrid characteristics - **Nutrient management** — Calculating fertilizer rates from soil test results, yield goals, and crop removal rates - **Yield analysis** — Identifying yield-limiting factors by correlating spatial yield patterns with other data layers - **Risk assessment** — Flagging fields or zones with data patterns that indicate elevated production risk ## Why This Matters for Developers Agronomic intelligence is what makes agricultural AI applications useful rather than generic. An LLM connected to FieldMCP through [MCP](/glossary/mcp) can invoke agronomic intelligence tools to provide recommendations grounded in both data and agronomic science, rather than relying solely on the model's training data. See the [tools reference](/docs/tools) for available intelligence operations. ## API Gateway URL: https://www.fieldmcp.com/glossary/api-gateway > A server that acts as a single entry point for API requests, handling authentication, rate limiting, and routing to backend services. An API gateway is a server that sits between client applications and backend services, acting as a single entry point for all API requests. It handles cross-cutting concerns — authentication, rate limiting, request routing, data transformation — so that backend services can focus on business logic. FieldMCP's MCP gateway is an API gateway purpose-built for agricultural data access. ## FieldMCP's Gateway Architecture The FieldMCP gateway runs in the cloud. It exposes a single MCP endpoint (`POST /mcp`) that accepts tool invocations from AI clients. Behind this endpoint, the gateway: 1. **Authenticates** — Validates [OAuth 2.1](/glossary/oauth-2-1) bearer tokens (ES256 JWTs) on every request 2. **Rate limits** — Enforces per-minute and monthly request limits based on subscription tier. See [rate limiting](/glossary/rate-limiting). 3. **Routes** — Maps MCP tool names to the appropriate agricultural data provider API 4. **Transforms** — [Normalizes](/glossary/data-normalization) provider-specific responses into FieldMCP's standard format 5. **Caches** — Uses Durable Objects for per-developer state management, reducing database roundtrips from 11-13 calls to 1 ## Why a Gateway (Not Direct API Access) Agricultural APIs like John Deere require provider-specific authentication flows, custom headers (`Accept: application/vnd.deere.axiom.v3+json`), pagination handling, and data format translation. The gateway absorbs this complexity so your application sends a simple MCP tool call and receives clean, normalized data. As FieldMCP adds support for additional providers (Climate FieldView, CNHi), the gateway routes to them transparently. Your integration code stays the same. ## Key Endpoints - `POST /mcp` — MCP tool invocations (requires Bearer JWT) - `GET /authorize` — OAuth 2.1 authorization initiation - `GET /oauth/callback` — OAuth callback handler - `GET /.well-known/jwks.json` — Public signing keys - `GET /health` — Health check ## Further Reading - [Quickstart guide](/docs/quickstart) - [Tools reference](/docs/tools) - [Authentication guide](/docs/authentication) ## Crop Scouting URL: https://www.fieldmcp.com/glossary/crop-scouting > The practice of systematically walking fields to observe and document crop conditions, pest pressure, and other agronomic issues. Crop scouting is the systematic inspection of growing crops to identify and document issues such as pest infestations, disease pressure, nutrient deficiencies, weed competition, and weather damage. For developers building agricultural software, scouting data represents georeferenced field observations that complement remote sensing and equipment data. ## Traditional vs. Data-Driven Scouting Traditional scouting involves an agronomist walking predetermined paths through a field, stopping at regular intervals to count insects, rate disease severity, or assess plant health. The scout records observations on paper or in a mobile app with GPS tagging. Data-driven scouting uses remote sensing to direct where scouts should look. Instead of walking the entire field, an AI application can analyze [NDVI imagery](/glossary/ndvi) to identify anomalous zones and generate a prioritized scouting route. This dramatically reduces time in the field while increasing detection rates. ## Scouting Data Structure A scouting observation typically includes: - GPS coordinates (point location) - Timestamp - Observation category (pest, disease, weed, nutrient, mechanical) - Severity rating (threshold-based or numeric scale) - Photos (geotagged) - Free-text notes - Growth stage of the crop at observation time ## Why Developers Build Scouting Integrations Scouting data closes the loop between remote observation and ground truth. Common use cases: - **AI-assisted identification** — Use image classification models to identify pests or diseases from scouting photos, connected through FieldMCP's [MCP interface](/glossary/mcp) - **Threshold alerting** — When pest counts exceed economic thresholds, automatically flag the field for treatment - **Prescription generation** — Convert scouting observations into spray [prescriptions](/glossary/planting-prescriptions) targeting only affected zones - **Historical analysis** — Correlate scouting records with [yield data](/glossary/yield-mapping) to quantify the yield impact of specific pest or disease events ## Getting Started FieldMCP provides tools for reading and writing scouting observations. See the [tools reference](/docs/tools) for available scouting operations. ## Data Normalization URL: https://www.fieldmcp.com/glossary/data-normalization > The process of transforming agricultural data from multiple providers into a consistent, standardized format. Data normalization is the process of converting data from multiple sources — each with its own schema, units, naming conventions, and quirks — into a single, consistent format. In agricultural software, this means transforming John Deere's API responses, Climate FieldView's data exports, and CNHi's telemetry streams into a unified data model that your application can consume without provider-specific logic. ## Why Normalization Is Necessary Agricultural data platforms differ in almost every dimension: - **Units** — One provider returns yield in bushels per acre, another in tonnes per hectare, another in kilograms per hectare - **Coordinate formats** — Some use `[lat, lng]`, others use `[lng, lat]`, some return projected coordinates - **Field identifiers** — Each provider has its own ID scheme, naming conventions, and hierarchy (organization > farm > field vs. client > operation > field) - **Timestamps** — Varying timezone handling, date formats, and precision - **Pagination** — Different cursor styles, page sizes, and link-following patterns Without normalization, every consumer of the data must handle every provider's format. This creates an N-by-M integration problem that grows multiplicatively. ## How FieldMCP Normalizes Data FieldMCP's [API gateway](/glossary/api-gateway) normalizes responses at the gateway layer before returning data through MCP tools: 1. **Schema mapping** — Provider-specific fields are mapped to FieldMCP's canonical schema 2. **Unit conversion** — All measurements are converted to standard units (metric with imperial alternatives available) 3. **Coordinate standardization** — All [geospatial data](/glossary/geospatial-data) is returned as GeoJSON in WGS 84 4. **ID namespacing** — Provider IDs are preserved but wrapped in a namespace to prevent collisions 5. **Pagination abstraction** — Provider-specific pagination is handled internally; clients receive complete result sets or standard cursor tokens ## Developer Benefits - **Write once** — Your application code handles one schema regardless of the upstream provider - **Add providers for free** — When FieldMCP adds support for a new platform, your existing integration works automatically - **Consistent error handling** — Provider-specific error codes are mapped to standard FieldMCP error types See the [tools reference](/docs/tools) for the normalized data schemas returned by each MCP tool. ## Equipment Telematics URL: https://www.fieldmcp.com/glossary/telematics > The remote monitoring of agricultural equipment through GPS tracking, engine diagnostics, and operational data transmitted from machines in real time. Equipment telematics is the technology that enables agricultural machines — tractors, combines, sprayers, planters — to transmit real-time operational data to cloud platforms. This includes GPS location, engine diagnostics, fuel consumption, ground speed, and implement-specific metrics like planting population or spray rate. For developers, telematics data is a continuous stream of machine activity that powers fleet management, operational analytics, and predictive maintenance. ## What Telematics Data Contains A telematics data stream from a modern agricultural machine typically includes: - **Position** — GPS coordinates, heading, and ground speed updated every few seconds - **Engine** — RPM, fuel rate, coolant temperature, hours of operation, diagnostic trouble codes (DTCs) - **Implement** — Application rate, section control status, seed population, working width - **Machine state** — Idle, traveling, working, or off - **CAN bus data** — Raw controller area network messages from onboard systems ## How Telematics Data Flows The machine's telematics control unit (TCU) transmits data via cellular connection to the manufacturer's cloud platform. For John Deere equipment, this data lands in [Operations Center](/glossary/operations-center), where it becomes accessible through APIs that FieldMCP integrates with. Data is typically available in near-real-time (30-second to 5-minute delay) for active machines and as historical records for completed operations. ## Developer Use Cases - **Fleet tracking** — Show real-time machine locations on a map during planting or harvest season - **Utilization analytics** — Calculate idle time, productive hours, and fuel efficiency across a fleet - **Predictive maintenance** — Monitor engine diagnostics and alert on patterns that precede failures - **Operation verification** — Confirm that field operations (planting, spraying) were completed as planned by matching telematics data against [prescriptions](/glossary/planting-prescriptions) - **Automated record-keeping** — Use machine activity to auto-populate field operation logs in the [FMIS](/glossary/fmis) ## Accessing Telematics Data FieldMCP exposes telematics data through its MCP tools. See the [tools reference](/docs/tools) for available equipment and machine data operations. ## Farm Management Information System (FMIS) URL: https://www.fieldmcp.com/glossary/fmis > Software that helps farmers plan, monitor, and document crop production activities and field operations. A Farm Management Information System (FMIS) is software that centralizes the planning, monitoring, and record-keeping of crop production activities. It is the farmer's equivalent of an ERP system — tracking inputs, operations, yields, and compliance documentation across all fields and seasons. ## What an FMIS Does An FMIS typically handles: - **Field records** — Boundaries, soil types, crop history, ownership/lease data - **Operation planning** — Planting schedules, fertilizer programs, spray timing - **Execution tracking** — As-applied maps from equipment showing what actually happened in the field - **Harvest documentation** — Yield data tied to specific fields and varieties - **Compliance** — Regulatory reporting, organic certification records, sustainability metrics ## Examples You'll Encounter The most common FMIS platforms that FieldMCP integrates with or that your users likely depend on: - **John Deere Operations Center** — The dominant platform in North America. FieldMCP provides direct API access to its data through the [Operations Center integration](/glossary/operations-center). - **Climate FieldView** — Bayer's platform focused on imagery and planting analytics. - **Granular (Corteva)** — Enterprise-focused farm management with strong financial tracking. ## Why This Matters for Developers When you integrate with agricultural APIs through FieldMCP, you are reading from and writing to FMIS data stores. The field boundaries you pull via `get_field_boundaries` live in an FMIS. The yield maps you query were uploaded from combine monitors into an FMIS. Understanding this context helps you: 1. **Design better UX** — Farmers already organize their world by farm, field, and season. Match that mental model. 2. **Avoid data conflicts** — An FMIS is the system of record. Write operations should respect existing data rather than overwriting it. 3. **Handle seasonality** — FMIS data is inherently time-series. Always scope queries to a crop year. ## Accessing FMIS Data FieldMCP's MCP tools abstract away provider-specific FMIS APIs. See the [tools reference](/docs/tools) for available operations and the [data normalization glossary entry](/glossary/data-normalization) to understand how cross-platform data is unified. ## Field Boundaries URL: https://www.fieldmcp.com/glossary/field-boundaries > GeoJSON polygons that define the geographic extent of agricultural fields, serving as the spatial foundation for all field-level data. Field boundaries are georeferenced polygons that define where an agricultural field starts and ends. They are the foundational spatial unit in agricultural software — every other data layer (yield maps, prescriptions, soil samples, imagery) is clipped to or referenced against field boundaries. Through FieldMCP, boundaries are returned as GeoJSON Polygon or MultiPolygon features. ## What a Field Boundary Contains A field boundary object from FieldMCP typically includes: - **Geometry** — A GeoJSON polygon with coordinates in WGS 84 (longitude, latitude) - **Name** — The farmer's name for the field (e.g., "North 80", "River Bottom") - **Area** — Calculated acreage or hectarage - **Farm association** — Which farm or operation the field belongs to - **Provider ID** — The upstream identifier in John Deere or other platforms - **Crop history** — What was planted in recent seasons (when available) ## Why Boundaries Matter Field boundaries are the join key for agricultural data. When you query yield data, you query it for a specific field. When you generate a prescription, you generate it within a field's boundary. When you display NDVI imagery, you clip it to field boundaries. Without accurate boundaries, no other spatial data is useful. ## Common Challenges - **Boundary versioning** — Fields get split, merged, or redrawn between seasons. Always query boundaries for a specific crop year. - **Sub-field management** — Some operations manage zones within a field separately. FieldMCP supports querying management zones when the provider makes them available. - **Overlapping boundaries** — Different providers may have slightly different boundary coordinates for the same physical field. FieldMCP's [data normalization](/glossary/data-normalization) helps reconcile these differences. ## Accessing Field Boundaries FieldMCP provides MCP tools for listing and retrieving field boundaries. A typical workflow starts with listing all fields for an organization, then querying specific fields for detailed boundary geometry and associated data. See the [tools reference](/docs/tools) for available field boundary operations and the [geospatial data glossary entry](/glossary/geospatial-data) for format details. ## Geospatial Data URL: https://www.fieldmcp.com/glossary/geospatial-data > Data that includes geographic coordinates, enabling it to be mapped and analyzed in relation to specific locations on Earth. Geospatial data is any data that includes a geographic component — coordinates, boundaries, or spatial relationships — allowing it to be placed on a map and analyzed in relation to physical locations. In agricultural software, nearly everything is geospatial: fields are polygons, yield measurements are points, prescriptions are zones, and equipment tracks are linestrings. ## Common Geospatial Formats in Agriculture When working with FieldMCP's APIs, you'll encounter these formats: - **GeoJSON** — The default format for web APIs. FieldMCP returns [field boundaries](/glossary/field-boundaries), scouting observations, and prescription zones as GeoJSON features with properties. Human-readable and natively supported by every mapping library. - **Shapefile** — Legacy format still dominant in desktop GIS and equipment controllers. A single "shapefile" is actually 3-6 files (.shp, .dbf, .shx, .prj, etc.). - **ISO-XML** — ISOBUS standard format for task data exchange between farm software and equipment controllers. Used for [prescriptions](/glossary/planting-prescriptions) and as-applied records. - **GeoTIFF** — Raster format for imagery layers like [NDVI](/glossary/ndvi). Each pixel has a value and a geographic coordinate. ## Coordinate Reference Systems Agricultural geospatial data almost universally uses WGS 84 (EPSG:4326) — the same coordinate system as GPS. FieldMCP normalizes all provider data to WGS 84 longitude/latitude pairs. If you need to calculate areas or distances accurately, project to a local UTM zone first. ## Working with Geospatial Data For developers building on FieldMCP: - **Rendering** — Use Mapbox GL, Leaflet, or Deck.gl to visualize GeoJSON on interactive maps - **Analysis** — Turf.js handles client-side spatial operations (area calculation, point-in-polygon, buffering) - **Storage** — PostGIS extends PostgreSQL with spatial types and indexes if you need server-side queries ## Getting Started FieldMCP's MCP tools return geospatial data as GeoJSON by default. See the [tools reference](/docs/tools) and the [data normalization glossary entry](/glossary/data-normalization) for how cross-provider data is standardized. ## Harvest Data URL: https://www.fieldmcp.com/glossary/harvest-data > Georeferenced crop production data collected during harvest, including yield, moisture, and machine performance metrics. Harvest data is the collection of measurements recorded during crop harvesting — yield volume, grain moisture, machine speed, header position, and GPS coordinates — that together describe exactly what was produced and where. It is the definitive performance metric for a growing season and the most valuable dataset in [precision agriculture](/glossary/precision-agriculture). ## What Harvest Data Includes When you query harvest data through FieldMCP, you receive: - **Yield measurements** — Georeferenced points with crop volume (bushels/acre or tonnes/hectare). See [yield mapping](/glossary/yield-mapping) for details on how this data is collected. - **Moisture readings** — Grain moisture percentage at each point, essential for calculating dry yield and storage decisions. - **Machine data** — Combine speed, header width, separator loss, and other [telematics](/glossary/telematics) metrics recorded during harvest. - **Timestamps** — When each section of the field was harvested, enabling analysis of harvest timing and logistics. - **Crop identification** — What crop and variety was harvested in each field. ## Data Quality Considerations Raw harvest data requires cleaning before analysis. Common issues developers need to handle: - **Start/stop artifacts** — Yield sensors need time to stabilize when the combine starts a pass or turns at row ends. These readings produce artificial highs and lows. - **Overlap corrections** — Adjacent passes may overlap, creating duplicate measurements. - **Moisture calibration** — Onboard moisture sensors drift over time and may need calibration factors. - **GPS accuracy** — Sub-meter GPS errors accumulate at high harvest speeds. FieldMCP's [data normalization](/glossary/data-normalization) layer applies basic quality filters, but applications performing detailed analysis should implement additional cleaning. ## Developer Use Cases - **Season summaries** — Aggregate harvest data by field, farm, or region to produce production reports - **Year-over-year comparison** — Track yield trends across seasons to evaluate management changes - **Input ROI** — Correlate harvest data with input costs (seed, fertilizer, chemical) to calculate return on investment per zone ## Accessing Harvest Data FieldMCP provides MCP tools for querying harvest data by field and season. See the [tools reference](/docs/tools) for available operations. ## John Deere Operations Center URL: https://www.fieldmcp.com/glossary/operations-center > John Deere's cloud platform for managing farm data, equipment, and operations — the primary data source FieldMCP integrates with. John Deere Operations Center is Deere & Company's cloud-based farm management platform. It aggregates data from John Deere equipment, displays it on maps, and provides tools for planning operations and analyzing performance. For developers, Operations Center is the upstream API that FieldMCP connects to — when you query field boundaries, yield data, or equipment telematics through FieldMCP, the data originates from Operations Center. ## What Operations Center Contains Operations Center stores and organizes: - **Field boundaries** — [GeoJSON polygons](/glossary/field-boundaries) for every field in the farmer's operation - **Machine data** — Real-time and historical [equipment telematics](/glossary/telematics) from connected John Deere machines - **Agronomic data** — [Yield maps](/glossary/yield-mapping), as-applied records, [planting prescriptions](/glossary/planting-prescriptions), and [soil sample](/glossary/soil-sampling) results - **Imagery** — Satellite [NDVI](/glossary/ndvi) layers and crop health maps - **Organization structure** — Multi-level hierarchy of organizations, farms, fields, and user permissions ## The Operations Center API John Deere exposes Operations Center data through a REST API at `api.deere.com/platform` (production) or `sandboxapi.deere.com/platform` (sandbox). Key characteristics: - **Authentication** — OAuth 2.0 via Okta with scopes `ag1 ag2 ag3 offline_access` - **Content type** — Custom media type: `application/vnd.deere.axiom.v3+json` - **Pagination** — HATEOAS-style link navigation with embedded resources - **Rate limits** — Undocumented but enforced; aggressive polling triggers throttling ## Why FieldMCP Abstracts Operations Center The Operations Center API is powerful but complex. FieldMCP's [API gateway](/glossary/api-gateway) handles the provider-specific authentication flow, custom headers, HATEOAS pagination, and response [normalization](/glossary/data-normalization) so your application deals with clean MCP tool calls instead of raw REST responses. ## Getting Started Connect your AI application to FieldMCP to access Operations Center data through a standardized [MCP](/glossary/mcp) interface. See the [quickstart guide](/docs/quickstart) and [authentication docs](/docs/authentication). ## Machine-to-Machine Authentication URL: https://www.fieldmcp.com/glossary/machine-to-machine-auth > An authentication pattern where services authenticate directly with each other without human interaction, using client credentials. Machine-to-machine (M2M) authentication is an authentication pattern where one service authenticates directly with another without any human user present. Unlike interactive [OAuth 2.1](/glossary/oauth-2-1) flows where a user signs in through a browser, M2M auth uses pre-shared credentials (typically a client ID and client secret) to obtain access tokens programmatically. ## When M2M Auth Is Used M2M authentication applies to server-side scenarios where no human is available to click through a consent screen: - **Backend services** — A data pipeline that pulls field data on a schedule - **Automated analysis** — A cron job that runs [agronomic intelligence](/glossary/agronomic-intelligence) rules nightly - **Inter-service communication** — FieldMCP's dashboard calling the gateway's internal endpoints - **CI/CD systems** — Automated tests that need to authenticate against staging environments ## How It Works in FieldMCP FieldMCP uses two M2M authentication patterns: ### Internal Service Communication The dashboard communicates with the gateway using a shared `INTERNAL_SECRET`. The dashboard includes this secret in requests to internal endpoints like `POST /internal/invalidate-cache`. This is a simple shared-secret pattern suitable for trusted service-to-service calls within the same infrastructure. ### OAuth 2.1 Client Credentials For external M2M access, FieldMCP supports the OAuth 2.1 client credentials grant. The service sends its client ID and secret to the token endpoint and receives a scoped access token — no redirect flow needed. The returned JWT has the same format and validation rules as interactive tokens. ## Security Considerations M2M credentials require careful handling: - **Secret rotation** — Client secrets should be rotated regularly. FieldMCP supports multiple active secrets during rotation periods. - **Least privilege** — M2M tokens should be scoped to only the permissions the service needs. - **Secure storage** — Store secrets in environment variables or a secrets manager, never in code or version control. ## Further Reading - [Authentication guide](/docs/authentication) - [OAuth 2.1 glossary entry](/glossary/oauth-2-1) - [Rate limiting](/glossary/rate-limiting) — M2M clients are subject to the same rate limits ## Model Context Protocol (MCP) URL: https://www.fieldmcp.com/glossary/mcp > An open protocol that standardizes how AI applications connect to external data sources and tools. Model Context Protocol (MCP) is an open protocol that defines how AI applications — particularly large language models — connect to external data sources, APIs, and tools through a standardized interface. Think of it as USB-C for AI integrations: one plug, many devices. ## Why MCP Exists Before MCP, every AI application that needed external data had to build custom integrations for each data source. A developer connecting Claude to John Deere would write completely different code than one connecting it to Climate FieldView. MCP eliminates this N-to-N integration problem by defining a common protocol that any AI client and any data provider can implement. ## How It Works An MCP server exposes two primitives: - **Tools** — Functions the AI can call (e.g., `get_field_boundaries`, `list_equipment`). Each tool has a typed schema describing its inputs and outputs. - **Resources** — Data the AI can read (e.g., field maps, harvest summaries). Resources are identified by URIs. The AI client (Claude, GPT, or your own app) connects to one or more MCP servers over a standard transport (HTTP with server-sent events or stdio). The client discovers available tools and resources at connection time, then invokes them as needed during a conversation. ## MCP in FieldMCP FieldMCP is an MCP server that provides unified access to agricultural data platforms. Instead of integrating directly with each provider's proprietary API, you connect your AI application to FieldMCP's MCP gateway, which handles authentication, data normalization, and provider-specific quirks behind a single interface. The gateway runs in the cloud and supports the full MCP specification including tool discovery, typed invocations, and streaming responses. See the [quickstart guide](/docs/quickstart) to connect your first AI client, or read the [authentication docs](/docs/authentication) to understand how OAuth 2.1 secures the connection. ## Further Reading - [MCP specification](https://modelcontextprotocol.io) - [FieldMCP tools reference](/docs/tools) ## NDVI (Normalized Difference Vegetation Index) URL: https://www.fieldmcp.com/glossary/ndvi > A satellite or drone-derived index that quantifies vegetation health by comparing near-infrared and visible red light reflectance. NDVI (Normalized Difference Vegetation Index) is a numerical indicator that measures vegetation health by comparing how much near-infrared (NIR) light plants reflect versus how much visible red light they absorb. The formula is simple: `NDVI = (NIR - Red) / (NIR + Red)`. Values range from -1 to 1, where healthy vegetation typically scores 0.3-0.9 and bare soil or water scores below 0.2. ## Why NDVI Works Healthy plants absorb red light for photosynthesis and strongly reflect near-infrared light. Stressed or sparse vegetation absorbs less red and reflects less NIR, producing a lower NDVI value. This makes NDVI a reliable proxy for canopy density, chlorophyll content, and overall crop vigor — measurable from hundreds of kilometers away via satellite. ## Data Sources NDVI imagery reaches agricultural platforms through several channels: - **Satellite** — Sentinel-2 (ESA, free, 10m resolution, 5-day revisit) and Landsat (NASA/USGS, free, 30m resolution) are the most common sources. Commercial providers offer higher resolution. - **Drone** — Multispectral cameras on UAVs capture field-level NDVI at centimeter resolution. Higher quality but labor-intensive. - **Aerial** — Manned aircraft with multispectral sensors, used for regional surveys. ## How Developers Use NDVI Through FieldMCP, NDVI data is accessible as georeferenced raster or zonal summary data. Common applications include: - **In-season scouting prioritization** — Identify low-NDVI zones that need physical inspection. See [crop scouting](/glossary/crop-scouting). - **Variable rate nitrogen** — NDVI correlates with nitrogen uptake, enabling mid-season [VRT](/glossary/variable-rate-technology) top-dress prescriptions. - **Yield prediction** — Mid-season NDVI is a strong predictor of final [yield](/glossary/yield-mapping), especially during grain fill. - **Anomaly detection** — Compare current NDVI against historical baselines to flag emerging problems. ## Accessing NDVI Data FieldMCP's imagery tools provide NDVI data through the MCP interface. See the [tools reference](/docs/tools) for available imagery operations. ## OAuth 2.1 URL: https://www.fieldmcp.com/glossary/oauth-2-1 > The modern authorization framework that FieldMCP uses to securely delegate access to agricultural data without sharing credentials. OAuth 2.1 is an authorization framework that allows users to grant third-party applications access to their data without sharing passwords. It consolidates the best practices from OAuth 2.0 and its security extensions (PKCE, token binding, refresh token rotation) into a single, simplified specification. FieldMCP uses OAuth 2.1 as its sole authentication mechanism. ## How OAuth 2.1 Works in FieldMCP FieldMCP implements a two-hop PKCE authorization flow: 1. **Client to FieldMCP** — Your AI application redirects the user to FieldMCP's `/authorize` endpoint with a PKCE code challenge. FieldMCP validates the request and initiates the upstream authorization. 2. **FieldMCP to John Deere** — FieldMCP redirects the user to John Deere's Okta identity provider. The user signs in with their John Deere credentials and grants consent. 3. **Callback chain** — John Deere redirects back to FieldMCP's `/oauth/callback`, which exchanges the authorization code for tokens. FieldMCP then issues its own tokens to your application. ## Token Types - **Access tokens** — ES256-signed JWTs with a 1-hour expiry, audience-restricted to the MCP endpoint. Passed as `Bearer` tokens in the `Authorization` header. - **Refresh tokens** — Opaque 32-byte tokens, SHA-256 hashed before storage. Used to obtain new access tokens without re-prompting the user. ## Why OAuth 2.1 (Not API Keys) FieldMCP previously supported API keys but removed them entirely. OAuth 2.1 provides: - **Scoped access** — Tokens are restricted to specific permissions, not blanket access - **Automatic expiry** — Compromised tokens stop working after 1 hour - **User consent** — The data owner explicitly approves each application's access - **Auditability** — Token issuance and refresh events create a clear access trail ## Verifying Tokens FieldMCP publishes its public signing key at `/.well-known/jwks.json`. If you need to verify access tokens independently, fetch the JWKS and validate the ES256 signature, expiry, and audience claims. ## Further Reading - [Authentication guide](/docs/authentication) - [Machine-to-machine auth](/glossary/machine-to-machine-auth) for service-to-service flows ## Planting Prescriptions URL: https://www.fieldmcp.com/glossary/planting-prescriptions > Georeferenced maps that specify variable seeding rates across different zones of a field for use by precision planting equipment. A planting prescription is a digital map that tells a planter how many seeds to plant at each location within a field. Instead of a uniform seeding rate, the prescription defines zones with different target populations — higher rates in productive areas that can support more plants, lower rates in poor-performing zones where extra seed is wasted. The planter reads this map in real time via GPS and adjusts seed meters automatically. ## Prescription Structure Through FieldMCP, planting prescriptions are represented as GeoJSON FeatureCollections where each feature is a zone with properties: - **Geometry** — Polygon defining the zone boundary within the [field boundary](/glossary/field-boundaries) - **Rate** — Target seeding rate (seeds per acre or plants per hectare) - **Product** — Seed variety/hybrid identifier - **Depth** — Target planting depth (when variable) ## How Prescriptions Are Created Prescriptions are typically generated from one or more data layers: 1. **Yield-based** — Analyze multi-year [yield maps](/glossary/yield-mapping) to identify productivity zones. High-yield zones get higher seeding rates. 2. **Soil-based** — Use [soil sampling](/glossary/soil-sampling) data (organic matter, water-holding capacity) to define zones correlated with yield potential. 3. **Imagery-based** — Use [NDVI](/glossary/ndvi) or bare-soil imagery to delineate management zones. 4. **AI-generated** — LLMs connected through FieldMCP's [MCP interface](/glossary/mcp) can analyze multiple data layers simultaneously and generate optimized prescriptions. ## Developer Integration Patterns - **Read existing prescriptions** — Pull prescriptions from the farmer's [FMIS](/glossary/fmis) to display or analyze - **Write new prescriptions** — Generate prescriptions programmatically and push them to the farmer's equipment platform - **Compare planned vs. actual** — Match the prescription against as-applied data from [equipment telematics](/glossary/telematics) to measure execution accuracy ## Getting Started See the [tools reference](/docs/tools) for prescription-related MCP tools and the [variable rate technology glossary entry](/glossary/variable-rate-technology) for the broader VRT context. ## Precision Agriculture URL: https://www.fieldmcp.com/glossary/precision-agriculture > A farming management approach that uses data and technology to optimize crop production at a sub-field level. Precision agriculture is a farming management strategy that uses sensor data, GPS positioning, and analytics to make field-level decisions at sub-field resolution. Instead of treating an entire field uniformly, precision ag applies the right input (seed, fertilizer, water) at the right rate, in the right place, at the right time. ## Why Developers Should Care If you're building agricultural software, precision agriculture is the domain your users operate in. Every API call you make to John Deere or Climate FieldView ultimately serves a precision ag workflow — whether that's pulling yield maps, pushing variable-rate prescriptions, or reading equipment telemetry. Understanding the domain helps you build better integrations. ## Core Components Precision agriculture depends on several data layers that FieldMCP exposes through its MCP tools: - **Field boundaries** — GeoJSON polygons defining where each field starts and ends. See [field boundaries](/glossary/field-boundaries). - **Yield data** — Georeferenced harvest measurements showing production variability across a field. See [yield mapping](/glossary/yield-mapping). - **Soil data** — Nutrient levels, pH, organic matter sampled at grid points. See [soil sampling](/glossary/soil-sampling). - **Prescriptions** — Variable-rate application maps that tell equipment how much input to apply at each location. See [variable rate technology](/glossary/variable-rate-technology). - **Imagery** — Satellite or drone-captured vegetation indices like [NDVI](/glossary/ndvi) that reveal crop health patterns. ## The Data Challenge The biggest pain point in precision ag software is data fragmentation. A single farm might use John Deere for equipment, Climate FieldView for imagery, and a local co-op for soil sampling. Each system stores data in different formats with different APIs. FieldMCP addresses this by [normalizing agricultural data](/glossary/data-normalization) from multiple providers into a consistent interface that AI applications can query through a single MCP connection. ## Getting Started Use FieldMCP's [agronomic intelligence tools](/docs/tools) to access precision agriculture data programmatically. The [quickstart guide](/docs/quickstart) walks through connecting to your first field data. ## Rate Limiting URL: https://www.fieldmcp.com/glossary/rate-limiting > A mechanism that restricts how many API requests a client can make within a given time window to protect service availability. Rate limiting is a traffic control mechanism that restricts the number of API requests a client can make within a defined time window. It protects backend services from overload, ensures fair resource allocation across users, and mitigates abuse. FieldMCP implements multiple rate limiting layers, each targeting a different threat vector. ## FieldMCP's Rate Limiting Architecture FieldMCP uses three complementary rate limiting strategies: ### Authentication Failure Limiting IP-based rate limiting that tracks failed authentication attempts. After 25 failures within a 900-second (15-minute) window, the IP is temporarily blocked. This prevents credential stuffing and brute-force attacks against the [OAuth 2.1](/glossary/oauth-2-1) endpoints. State is stored in the `cache.rate_limits` PostgreSQL table and cleaned by a pg_cron job every 5 minutes. ### Per-Minute Request Limiting A per-developer counter maintained in memory within the DeveloperState Durable Object. Limits vary by subscription tier: | Tier | Requests/minute | |------|----------------| | Free | 60 | | Developer | 100 | | Startup | 500 | | Enterprise | 1,000 | Because this counter lives in the Durable Object's memory, it resets when the Worker restarts. This is intentional — per-minute limits are a burst protection mechanism, not a billing control. ### Monthly Usage Limiting An atomic counter that tracks total requests per developer per calendar month. Implemented via a PostgreSQL RPC function with row-level locking to prevent race conditions. The Durable Object batches flushes (every 30 seconds or 10 requests) to reduce database writes while maintaining accuracy. ## Handling Rate Limit Responses When a rate limit is hit, FieldMCP returns HTTP 429 with a `Retry-After` header indicating how many seconds to wait. Well-behaved clients should: 1. Respect the `Retry-After` value 2. Implement exponential backoff for repeated 429s 3. Monitor their usage against limits proactively via the dashboard ## Further Reading - [API gateway architecture](/glossary/api-gateway) - [Dashboard usage monitoring](/docs/dashboard) ## Soil Sampling URL: https://www.fieldmcp.com/glossary/soil-sampling > The practice of collecting and analyzing soil samples at georeferenced points to map nutrient variability across a field. Soil sampling is the practice of collecting physical soil cores at known GPS coordinates across a field, sending them to a laboratory for chemical analysis, and mapping the results to understand spatial variability in soil nutrients, pH, organic matter, and other properties. For developers, soil sample data is a key input layer for agronomic decision-making algorithms. ## Sampling Methods There are two primary approaches, both producing georeferenced data points: - **Grid sampling** — Samples are taken on a regular grid (typically 2.5-acre cells). Simple and systematic, but may miss important variability between grid points. - **Zone sampling** — Samples are taken from management zones defined by yield data, imagery, or electrical conductivity maps. More efficient but requires prior spatial data to define zones. ## Data Structure A soil sample result set, as returned through FieldMCP's APIs, typically includes: - GPS coordinates of each sample point - Nutrient levels: nitrogen (N), phosphorus (P), potassium (K), sulfur (S), and micronutrients - Soil pH and buffer pH - Organic matter percentage - Cation exchange capacity (CEC) - Sample depth (commonly 0-6" and 6-24") ## Why Soil Data Matters for Software Soil samples are the foundation of [variable rate technology](/glossary/variable-rate-technology) prescriptions. If a zone tests low in phosphorus, the prescription increases the P fertilizer rate there. If pH is too low, lime is prescribed. Without soil data, prescriptions are guesses. For AI-powered agronomic applications, soil data provides critical context. An LLM connected to FieldMCP can combine soil test results with [yield maps](/glossary/yield-mapping) and [NDVI imagery](/glossary/ndvi) to generate more accurate recommendations than any single data layer alone. ## Accessing Soil Data Soil sample data flows through the farmer's [FMIS](/glossary/fmis) and is accessible via FieldMCP's data tools. See the [tools reference](/docs/tools) for available soil data operations. ## Variable Rate Technology (VRT) URL: https://www.fieldmcp.com/glossary/variable-rate-technology > Technology that enables field equipment to automatically adjust input application rates based on prescription maps. Variable Rate Technology (VRT) is a system that allows agricultural equipment to automatically vary the rate of inputs — seed, fertilizer, chemicals, or water — across different zones of a field based on a digital prescription map. Instead of applying a flat rate everywhere, VRT matches inputs to each area's specific needs. ## How VRT Works A VRT workflow has three stages: 1. **Data collection** — Gather spatial data about field variability. This includes [yield maps](/glossary/yield-mapping), [soil samples](/glossary/soil-sampling), [NDVI imagery](/glossary/ndvi), and elevation data. 2. **Prescription creation** — An agronomist or algorithm divides the field into management zones and assigns target rates to each zone. The result is a prescription map — a georeferenced file (typically Shapefile or ISO-XML) that the equipment controller can read. 3. **Execution** — The equipment reads the prescription and a GPS receiver. As the machine moves through the field, the controller adjusts application hardware (seed meters, spray nozzles, spreader gates) in real time to match the prescribed rate for the current location. ## Prescription Formats Prescriptions are stored as vector or raster spatial data. Through FieldMCP, you can read and write prescriptions as GeoJSON with rate attributes. The [planting prescriptions glossary entry](/glossary/planting-prescriptions) covers the specific format for seeding operations. ## Why Developers Build VRT Integrations VRT is where agricultural data becomes actionable. Building software that generates or optimizes prescriptions means your code directly influences what happens in the field. Common integration patterns: - **AI-generated prescriptions** — Use LLMs connected via MCP to analyze multi-year yield data and soil samples, then generate optimized rate recommendations - **Prescription validation** — Check that rates fall within agronomic bounds before sending to equipment - **As-applied comparison** — Compare the prescription (what was planned) against as-applied data (what actually happened) to measure execution accuracy ## Getting Started See the [tools reference](/docs/tools) for prescription-related MCP tools and the [quickstart guide](/docs/quickstart) for connecting your application. ## Yield Mapping URL: https://www.fieldmcp.com/glossary/yield-mapping > The process of collecting georeferenced harvest data to visualize crop production variability across a field. Yield mapping is the process of recording georeferenced crop production data during harvest to create a spatial map of yield variability within a field. A yield map shows exactly where a field produced 250 bushels per acre versus 180 bushels per acre, enabling data-driven decisions about inputs and management. ## How Yield Data Is Collected Modern combines and harvesters are equipped with yield monitors that record three measurements simultaneously: - **Grain flow** — An impact or optical sensor measuring the volume of grain passing through the combine - **Moisture** — A sensor measuring grain moisture content for dry-weight normalization - **GPS position** — Sub-meter accuracy coordinates for each measurement point These sensors log data points every 1-3 seconds, producing thousands of georeferenced readings per field. The raw data is uploaded from the machine to the farmer's FMIS (typically [John Deere Operations Center](/glossary/operations-center)) where it becomes accessible via API. ## Data Format Through FieldMCP, yield data is returned as a collection of georeferenced points, each containing: - Latitude/longitude coordinates - Yield value (typically bushels/acre or tonnes/hectare) - Moisture percentage - Timestamp - Crop type This data often requires cleaning — GPS drift at row ends, overlapping passes, and moisture sensor lag produce artifacts that need filtering before analysis. ## Why Developers Use Yield Data Yield maps are the ground truth for [agronomic intelligence](/glossary/agronomic-intelligence). Common applications include: - **Management zone delineation** — Clustering yield patterns across multiple years to identify consistently high- and low-performing areas - **Input ROI analysis** — Correlating yield response with fertilizer or seed rate to optimize spending - **Anomaly detection** — Flagging yield drops that may indicate drainage issues, pest pressure, or compaction ## Accessing Yield Data Use FieldMCP's harvest data tools to query yield maps programmatically. See the [harvest data glossary entry](/glossary/harvest-data) and the [tools reference](/docs/tools) for available endpoints. # Legal ## Privacy Policy URL: https://www.fieldmcp.com/legal/privacy # Privacy Policy **Effective Date:** September 12, 2026 **Last Updated:** January 10, 2026 --- ## 1. Introduction This Privacy Policy explains how FieldMCP LLC ("Company," "we," "us," or "our"), a Missouri limited liability company, collects, uses, shares, and protects information when you use the FieldMCP platform, APIs, dashboard, and related services (collectively, the "Service"). By using the Service, you agree to the collection and use of information as described in this Privacy Policy. If you do not agree, please do not use the Service. **This Service is intended for users in the United States only.** ### What is Personal Information? Personal information is any information that can be used to identify you. This includes information about you as a person (such as name and email address), your devices, payment details, and information about how you use the Service. It also includes any data that, when combined with other information, could identify you. --- ## 2. Information We Collect ### 2.1 Account Information When you create an account, we collect: | Data | Purpose | |------|---------| | **Email address** | Account identification, login, communications | | **Company name** | Account identification, billing | We do not collect or store passwords. Sign-in uses a one-time code sent to your email address, with optional time-based one-time-password (TOTP) multi-factor authentication. ### 2.2 Authentication Data When you register an application and connect farmer accounts, we store: | Data | Purpose | |------|---------| | **Application client ID** | Identifies your registered application | | **Encrypted OAuth tokens** | John Deere access and refresh tokens (encrypted at rest with ChaCha20-Poly1305) | | **JWT signing keys** | ES256 keys used to sign authentication tokens | | **Token expiration** | Automatic refresh scheduling | | **Last used timestamp** | Usage tracking and security monitoring | | **Creation date** | Record keeping | ### 2.3 Farmer Connection Data When you connect a farmer's account via OAuth, we store: | Data | Purpose | |------|---------| | **Farmer identifier** | Your internal name for this connection | | **OAuth access token** | API authentication (encrypted at rest) | | **OAuth refresh token** | Token renewal (encrypted at rest) | | **Token expiration** | Automatic refresh scheduling | | **Scopes** | Permissions granted (e.g., ag1, ag2, ag3) | | **Provider** | Which service (John Deere, etc.) | | **Organization data** | Farms/organizations from provider | | **Refresh status** | Success/failure of automatic refresh | | **Last refresh timestamp** | Monitoring token health | | **Re-auth flag** | Whether manual re-authorization needed | ### 2.4 Usage Data For each API request, we log: | Data | Purpose | |------|---------| | **Developer ID** | Associate usage with your account | | **OAuth session ID** | Track which session was used | | **Farmer connection ID** | Track which connection was used | | **Provider** | Which agricultural API (John Deere, etc.) | | **Tool name** | Which MCP tool was called | | **Timestamp** | When the request occurred | | **Response time** | Performance monitoring (milliseconds) | | **Status code** | Success/failure tracking | | **Error type** | Debugging (if applicable) | ### 2.5 Billing Data For paid subscriptions, we store: | Data | Purpose | |------|---------| | **Stripe customer ID** | Link to your Stripe account | | **Stripe subscription ID** | Track your subscription | | **Subscription tier** | Determine your rate limits | | **Subscription status** | Active, canceled, past due, etc. | | **Billing period dates** | Track subscription cycle | **Note:** We do not store payment card details. All payment information is handled directly by Stripe. ### 2.6 Security Data For security and abuse prevention, we collect: | Data | Purpose | |------|---------| | **IP addresses** | Rate limiting failed login attempts | | **Failed login counts** | Prevent brute force attacks | | **Request counts** | Enforce rate limits | This data is stored temporarily in cache tables and automatically deleted. ### 2.7 Sensitive Information "Sensitive information" refers to personal information that requires heightened protection, such as racial or ethnic origin, political opinions, religious beliefs, trade union membership, health information, sexual orientation, or biometric data. **We do not collect sensitive information.** Our Service is designed for agricultural data management and does not require or process any sensitive personal information categories. ### 2.8 Information from Third Parties When developers use our Service to connect farmer accounts via OAuth: - **Developer responsibility**: Developers represent and warrant that they have obtained the farmer's informed consent before connecting their account to our Service. - **Farmer data**: We receive OAuth tokens and basic account information from agricultural data providers (such as John Deere) on behalf of the farmer. This data is used solely to facilitate API access as directed by the developer. - **Protection**: We protect all information received through these connections as described in this Privacy Policy. If you are a farmer whose account has been connected by a developer and you have questions about how your data is being used, please contact both the developer who connected your account and us at legal@fieldmcp.com. ### 2.9 Cookies and Similar Technologies We use essential cookies to operate the Service: | Cookie | Purpose | Duration | |--------|---------|----------| | **Session cookie** | Maintain your authenticated session | Session (expires on logout) | | **Auth token** | Supabase authentication state | Session | We do not use advertising, analytics, or tracking cookies. We do not use cookies for cross-site tracking or behavioral advertising. --- ## 3. How We Use Your Information We collect and use your personal information for the business purposes described below, as permitted by the California Consumer Privacy Act (CCPA) and other applicable US state privacy laws. We only collect personal information that is reasonably necessary to provide our services to you. We use your information to: ### 3.1 Provide the Service - Authenticate your account and API requests - Process API calls to agricultural data providers - Manage and refresh OAuth tokens automatically - Display your usage statistics and connection status ### 3.2 Process Payments - Create and manage your Stripe customer account - Process subscription payments - Track your subscription status and tier ### 3.3 Enforce Limits and Security - Apply rate limits based on your subscription tier - Prevent abuse and unauthorized access - Block repeated failed authentication attempts - Detect and prevent fraudulent activity ### 3.4 Improve the Service - Monitor system performance and reliability - Identify and fix bugs - Analyze usage patterns to improve features ### 3.5 Communicate with You - Send service-related announcements - Notify you of security issues affecting your account - Respond to your support requests ### 3.6 Comply with Legal Obligations - Maintain records required by law - Respond to legal requests - Enforce our Terms of Service --- ## 4. How We Share Your Information ### 4.1 Service Providers We share information with third-party service providers who help us operate the Service: | Provider | Purpose | Data Shared | |----------|---------|-------------| | **Supabase** | Database, authentication, edge functions | All account data, usage logs, farmer connections | | **Stripe** | Payment processing | Email, subscription metadata, developer ID | | **John Deere** | Agricultural data API | OAuth tokens, API requests made on your behalf | | **Vercel** | Dashboard hosting | Session cookies, page requests | These providers are contractually obligated to protect your information and use it only for the purposes we specify. ### 4.2 Agricultural Data Providers When you make API requests, we transmit: - OAuth access tokens to authenticate with the provider - Your API requests to retrieve farmer data The farmer data returned passes through our Service but we do not store it beyond request processing. ### 4.3 Legal Requirements We may disclose your information if required to: - Comply with applicable law, regulation, or legal process - Respond to lawful requests from public authorities - Protect our rights, privacy, safety, or property - Enforce our Terms of Service - Protect against legal liability ### 4.4 Business Transfers If we are involved in a merger, acquisition, bankruptcy, or sale of assets, your information may be transferred as part of that transaction. You acknowledge that such transfers may occur. Any party that acquires us or our assets will be required to honor this Privacy Policy as the basis for any ownership or use rights over your information, and may only use your personal information according to this policy. We will notify you of any change in ownership or control. ### 4.5 With Your Consent We may share information with your explicit consent for purposes not described here. ### 4.6 What We Do NOT Do We do NOT: - Sell your personal information to third parties - Share your information for third-party advertising - Use your farmer connection data for our own purposes beyond providing the Service --- ## 5. Data Security We implement security measures to protect your information: ### 5.1 Technical Safeguards | Measure | Description | |---------|-------------| | **Token encryption** | OAuth tokens are encrypted at rest before storage | | **JWT signing** | ES256-signed JSON Web Tokens for authentication | | **Row-level security** | Database policies ensure you can only access your own data | | **HTTPS** | All data transmitted over encrypted connections | | **Rate limiting** | Authentication endpoints protected against brute force | | **Automatic cleanup** | Cache data automatically deleted every 5 minutes | ### 5.2 Operational Safeguards - Access to production systems is restricted - We use managed infrastructure providers with strong security practices - We monitor for suspicious activity - Our infrastructure providers (Supabase, Vercel, Stripe) maintain SOC2 Type II certifications and undergo regular independent security audits ### 5.3 Security Limitations No system is perfectly secure. We cannot guarantee absolute security. You are responsible for: - Keeping your account credentials confidential - Securing your OAuth credentials - Notifying us of suspected security incidents ### 5.4 Data Breach Notification In the event of a data breach that affects your personal information, we will: - Investigate the breach promptly - Take steps to mitigate any harm - Notify affected users as required by applicable law - Report to relevant authorities where legally required We will provide notification within the timeframes required by applicable law. For customers covered by our Data Processing Agreement, the breach notification timeline specified in the DPA applies. Notifications will include information about what data was affected and steps you can take to protect yourself. --- ## 6. Data Retention We retain your information for different periods based on the type of data: | Data | Retention | |------|-----------| | **OAuth tokens and credentials** | Deleted immediately upon a deletion request | | **Account profile, farmer/enterprise connections, usage logs, settings** | Deleted at the end of the 30-day recovery window; removed from backups in the normal course of our backup rotation | | **Billing and payment records** | Retained 7 years to satisfy federal and state tax record-keeping (IRS recordkeeping rules; applicable state sales/use-tax statutes). Payment transaction records are also independently retained by our payment processor, Stripe, under Stripe's own retention schedule, which runs in parallel with ours and is governed by Stripe's agreements, not ours. | ### 6.1 Active Accounts While your account is active, we retain all data necessary to provide the Service. ### 6.2 Cached Data Temporary cache data (rate limits, validated OAuth sessions) expires automatically and is cleaned up every 5 minutes. --- ## 7. Your Rights ### 7.1 Access Your Data You can access most of your data through the dashboard: - Account information in settings - OAuth connections and their metadata - Farmer connections and their status - Usage logs and analytics ### 7.2 Correct Your Data You can update your account information (email, company name) through the dashboard. ### 7.3 Account Closure and Data Deletion **Closing your account.** You may close your FieldMCP account at any time in Account Settings via "Delete Account." This immediately revokes your access and OAuth credentials and begins a 30-day recovery period during which you may restore your account by signing back in. After 30 days, your account and associated personal data are permanently deleted from our active systems; residual copies in backups are removed in the normal course of our backup rotation. **Privacy rights requests.** To submit a formal request regarding your personal information, including a request to know, to correct, or to delete independent of account closure, contact privacy@fieldmcp.com. This is the designated channel for statutory data-subject rights and is available to anyone whose information we hold, including former users and individuals who never created an account. Where required by applicable law, we will acknowledge your request within 10 business days and respond within 45 days (extendable once by 45 days with notice). **Relationship between the two.** Closing your account via the in-product button is a product feature you control directly and relies on your authenticated session. A formal privacy request to privacy@ is the designated statutory channel. We may retain limited information beyond these periods where reasonably necessary to comply with legal obligations, prevent fraud or abuse, resolve disputes, or enforce our agreements. ### 7.4 Export Your Data Usage data is viewable in the dashboard. Contact us at legal@fieldmcp.com if you need a data export. ### 7.5 File a Complaint If you believe we have violated your privacy rights or breached a data protection law, please contact us at legal@fieldmcp.com with full details of your concern. We will: - Acknowledge your complaint within 5 business days - Investigate your complaint promptly - Respond in writing within 30 days, explaining our findings and any steps we will take You also have the right to file a complaint with a regulatory body or data protection authority in your jurisdiction. ### 7.6 Opt Out of Communications To unsubscribe from our emails: - Click the "unsubscribe" link at the bottom of any email - Or contact us at legal@fieldmcp.com **Note**: You cannot opt out of essential service communications, including: - Security alerts affecting your account - Billing and payment notifications - Changes to our Terms of Service or Privacy Policy - Account verification messages We may need to verify your identity before processing opt-out requests. --- ## 8. California Privacy Rights If you are a California resident, you have additional rights under the California Consumer Privacy Act (CCPA): ### 8.1 Right to Know You have the right to request: - What personal information we have collected - The sources of that information - Our business purpose for collecting it - The categories of third parties with whom we share it - The specific pieces of personal information we hold about you ### 8.2 Right to Delete You have the right to request deletion of your personal information. We may retain your personal information notwithstanding a deletion request to the extent reasonably necessary to: (1) complete a transaction or perform a contract with you; (2) help ensure security and integrity, to the extent the use is reasonably necessary and proportionate; (3) debug to identify and repair errors that impair existing intended functionality; (4) exercise or enable the exercise of free speech or another right provided by law; (5) comply with the California Electronic Communications Privacy Act; (6) engage in qualifying research with your informed consent where deletion would render it impossible or seriously impaired; (7) enable solely internal uses reasonably aligned with your expectations and compatible with the context in which you provided the information; or (8) comply with a legal obligation. After deletion, we retain a confidential record that an account was deleted, consisting of a non-identifying internal identifier, timestamps, and a reason code, for security and legal-compliance purposes (Cal. Civ. Code §1798.105(c)(2)). ### 8.3 Right to Opt-Out of Sale **We do not sell your personal information or share it for cross-context behavioral advertising.** Because we do not engage in selling or sharing as defined by the CCPA, we are not required to provide a "Do Not Sell or Share My Personal Information" link. If you believe your information is being sold or shared, contact us at legal@fieldmcp.com. ### 8.4 Right to Non-Discrimination We will not discriminate against you for exercising your privacy rights. ### 8.5 How to Exercise Your Rights To exercise your CCPA rights, contact us at legal@fieldmcp.com. We will respond within 45 days. We may need to verify your identity before processing your request. ### 8.6 Authorized Agents You may designate an authorized agent to make requests on your behalf. We may require verification of both your identity and the agent's authorization. --- ## 9. Children's Privacy The Service is intended for business use by adults. We do not knowingly collect personal information from anyone under 18 years of age. If you believe we have collected information from a minor, please contact us immediately at legal@fieldmcp.com, and we will delete that information. --- ## 10. Third-Party Links The dashboard may contain links to third-party websites (e.g., John Deere, Stripe, documentation sites). We are not responsible for the privacy practices of these external sites. We encourage you to review their privacy policies. --- ## 11. International Users This Service is intended for users in the United States. If you access the Service from outside the United States, you do so at your own risk and are responsible for compliance with your local laws. We do not specifically target users in the European Union or other jurisdictions with additional data protection requirements (such as GDPR). --- ## 12. Changes to This Policy We may update this Privacy Policy from time to time. When we make changes: - We will update the "Last Updated" date at the top - For material changes, we will provide notice via: - Email to your registered address - Prominent notice on the dashboard If we intend to use your personal information for new purposes not described in this policy, we will notify you and, where required by law, obtain your consent before doing so. You will have the opportunity to opt out of such new uses where legally required. Your continued use of the Service after changes take effect constitutes acceptance of the updated policy. --- ## 13. Governing Law This Privacy Policy is governed by the laws of the State of Missouri, without regard to conflict of law principles. Any disputes relating to this Privacy Policy are subject to the exclusive jurisdiction of the state and federal courts located in Missouri. --- ## 14. Data Processing Agreement If you use the Service to process personal data on behalf of others (e.g., accessing farmer data through our APIs), our [Data Processing Agreement](/legal/dpa) governs our obligations as your data processor, including security measures, sub-processor management, data retention, and breach notification. --- ## 15. Contact Us If you have questions about this Privacy Policy or our data practices, please contact us: **FieldMCP LLC** Email: legal@fieldmcp.com Address: 117 SOUTH LEXINGTON ST STE 100 HARRISONVILLE, MO 64701 --- ## 16. Summary of Data Practices ### What We Collect - Account info (email, company name) - OAuth credentials (app client IDs, encrypted tokens) - Farmer connection data (identifiers, OAuth tokens, status) - Usage logs (requests, performance, errors) - Billing data (Stripe IDs, subscription status) ### How We Use It - Provide and improve the Service - Process payments - Enforce rate limits and prevent abuse - Communicate with you ### Who We Share With - Supabase (infrastructure) - Stripe (payments) - John Deere (agricultural API) - Vercel (hosting) - Legal authorities (when required) ### How Long We Keep It - OAuth tokens and credentials: Deleted immediately upon a deletion request - Account profile, connections, usage logs, settings: Deleted at end of the 30-day recovery window; removed from backups in the normal course of our backup rotation - Billing and payment records: Retained 7 years (federal and state tax record-keeping); also independently retained by Stripe under Stripe's own schedule ### Your Rights - Access, correct, and delete your data - California residents: Additional CCPA rights --- *This Privacy Policy is effective as of the date listed at the top of this document.* ## Terms of Service URL: https://www.fieldmcp.com/legal/terms # Terms of Service **Effective Date:** September 12, 2026 **Last Updated:** January 10, 2026 --- ## 1. Introduction and Acceptance These Terms of Service ("Terms") govern your access to and use of the FieldMCP platform, APIs, dashboard, and related services (collectively, the "Service") operated by FieldMCP LLC, a Missouri limited liability company ("Company," "we," "us," or "our"). By creating an account, accessing the Service, or using our APIs, you agree to be bound by these Terms. If you are using the Service on behalf of an organization, you represent that you have authority to bind that organization to these Terms. **If you do not agree to these Terms, do not use the Service.** **If you signed a separate agreement with us to access the Service with the same account, and that agreement has not ended, that separate agreement applies to your use of the Service instead of these Terms.** --- ## 2. Service Description FieldMCP is a Model Context Protocol (MCP) infrastructure platform that provides developers with unified access to agricultural data APIs. The Service includes: - **API Gateway**: Authenticated access to agricultural data providers through a single interface - **Provider Integrations**: Currently John Deere; future integrations may include Climate FieldView, CNHi, and others - **Developer Dashboard**: Account management, OAuth app management, farmer connection management, usage analytics, and billing - **Farmer Connection Management**: OAuth-based authorization flows for connecting farmer accounts - **Token Management**: Automatic refresh and lifecycle management of OAuth credentials The Service is designed for developers building agricultural applications and farmers who authorize access to their agricultural data. ### 2.1 Read-Only Data Access **The Service currently provides read-only access to equipment and agricultural data.** The Service retrieves information from third-party providers but does not and cannot: - Control, operate, or command any physical equipment - Start, stop, or modify equipment operations - Adjust machine settings or parameters - Schedule autonomous operations - Send commands to tractors, combines, sprayers, or any machinery - Trigger any action on physical equipment **Any future features involving equipment control or commands will be subject to additional terms and explicit user consent.** --- ## 3. Account Terms ### 3.1 Eligibility To use the Service, you must: - Be located in the United States (the Service is available to US-based users only) - Be at least 18 years old - Be capable of forming a binding contract - Use the Service for lawful purposes - Provide accurate and complete registration information ### 3.2 Account Registration When you create an account, you must provide: - A valid email address - Your company or business name You agree to keep this information accurate and up to date. ### 3.3 Account Security You are responsible for: - Maintaining the confidentiality of your account credentials - All activities that occur under your account - Notifying us immediately of any unauthorized access We are not liable for any loss resulting from unauthorized use of your account. ### 3.4 One Account Per Entity Each business entity may maintain only one account. Creating multiple accounts to circumvent rate limits, abuse free tiers, or evade termination is prohibited. ### 3.5 Geographic Restriction and GDPR Indemnification The Service is offered exclusively to customers located in the United States. Use by persons or entities subject to the EU General Data Protection Regulation or located in the European Economic Area is prohibited. Customer represents and warrants that it is not subject to GDPR and that no personal data of EU data subjects will be processed through the Service, and shall indemnify Provider for losses arising from breach of this representation. --- ## 4. Authentication ### 4.1 OAuth 2.1 Authentication The Service uses OAuth 2.1 for authentication. Each registered application is assigned a unique `client_id`. To access agricultural data: - Farmers authenticate directly with John Deere via a secure OAuth flow - Upon successful authentication, the Service issues ES256-signed JSON Web Tokens (JWTs) - Refresh tokens are used to maintain access without requiring repeated farmer login - You must securely store your `client_id` and any credentials associated with your application ### 4.2 Credential Security You are solely responsible for the security of your OAuth credentials. You must: - Store credentials securely and never commit them to version control - Never share credentials publicly or with unauthorized parties - Use environment variables or secure secret management systems - Notify us immediately if you suspect your credentials have been compromised ### 4.3 Token Revocation We may revoke OAuth tokens without notice if we determine they are being used in violation of these Terms or pose a security risk. You may disconnect farmer connections and revoke tokens at any time through the dashboard. --- ## 5. Farmer Connections ### 5.1 Authorization Responsibility When you connect a farmer's account through our OAuth flow: - **You** are responsible for obtaining the farmer's informed consent - **You** must have a lawful basis for accessing the farmer's data - **You** must comply with all applicable privacy laws and regulations - **You** must clearly explain to farmers what data you will access and how you will use it ### 5.2 Data Controller and Processor Roles For farmer data accessed through the Service: - **You** are the data controller responsible for determining the purposes and means of processing - **We** act as a data processor, processing farmer data on your behalf according to your instructions - **Farmers** retain ownership of their agricultural data ### 5.3 Token Storage We store OAuth tokens (access and refresh tokens) for farmer connections to enable API access and automatic token refresh. These tokens are encrypted with ChaCha20-Poly1305 authenticated encryption (with quarterly key rotation) and stored in our database with row-level security, ensuring only you can access your connections. ### 5.4 Connection Failures If a farmer connection fails (e.g., farmer revokes access, token refresh fails), the connection will be marked as requiring re-authentication. You are responsible for guiding your users through the re-authorization process. --- ## 6. Acceptable Use Policy You agree NOT to: ### 6.1 Illegal Activities - Use the Service for any unlawful purpose - Violate any applicable laws or regulations - Infringe on intellectual property rights ### 6.2 System Abuse - Attempt to circumvent rate limits or usage quotas - Interfere with or disrupt the Service or servers - Probe, scan, or test vulnerabilities without authorization - Introduce malware, viruses, or malicious code ### 6.3 Data Misuse - Access data you are not authorized to access - Scrape or bulk extract data beyond normal API usage patterns - Resell raw API access without adding substantial value - Use farmer data in ways not consented to by the farmer ### 6.4 Reverse Engineering - Reverse engineer, decompile, or disassemble any part of the Service - Attempt to derive source code or underlying algorithms - Create derivative works based on the Service ### 6.5 Misrepresentation - Impersonate any person or entity - Misrepresent your affiliation with any person or entity - Provide false information during registration --- ## 7. Billing and Payment ### 7.1 Subscription Tiers We offer multiple subscription tiers with varying request limits and rate limits. Current pricing, features, and limits for each tier are available on our [Pricing Page](/pricing). The pricing page is incorporated by reference into these Terms. In the event of a conflict between these Terms and the pricing page, these Terms govern except with respect to current prices and usage limits. ### 7.2 Payment Processing Payments are processed by Stripe. By subscribing to a paid tier, you agree to Stripe's terms of service. You authorize us to charge your payment method on a recurring monthly basis. ### 7.3 Refunds Subscription fees are non-refundable except where required by applicable law or as otherwise provided in these Terms (see Section 15.2). We do not provide refunds for: - Partial month usage - Unused API requests - Cancellation before period end - Dissatisfaction with the Service ### 7.4 Automatic Renewal Paid subscriptions automatically renew each billing cycle. You may cancel at any time before your next billing date. Cancellation takes effect at the end of the current billing period. ### 7.5 Rate Limit Enforcement If you exceed your tier's rate limits: - Per-minute limits: Requests are rejected with HTTP 429 status - Monthly limits: Requests are rejected until the next billing cycle We do not charge overage fees; your service is simply rate-limited. ### 7.6 Price Changes We may change our prices with 30 days' notice. Price changes take effect at the start of your next billing cycle after the notice period. ### 7.7 Fair Use Subscription tiers are priced for typical usage patterns. If your usage materially exceeds what is typical for your tier — including but not limited to sustained operation at or near rate limits, usage patterns that impose disproportionate infrastructure cost, or usage that degrades service for other customers — we reserve the right to: - Contact you to discuss your usage and propose an appropriate plan or custom pricing - Require migration to a higher tier or custom agreement within 30 days of written notice - Apply reasonable rate limits to align usage with your tier If we cannot reach mutual agreement within 30 days, either party may terminate the subscription effective at the end of the current billing period with no further obligation. --- ## 8. Service Availability ### 8.1 Service Availability Uptime commitments, if any, are set forth in our Service Level Agreement. In the absence of an applicable SLA for your subscription tier, the Service is provided on an "as available" basis without uptime guarantees. We may perform maintenance that temporarily interrupts the Service. ### 8.2 Third-Party Dependency The Service depends on third-party APIs (John Deere, etc.) that are outside our control. We are not responsible for: - Third-party API outages or degraded performance - Changes to third-party APIs that affect functionality - Data accuracy or completeness from third-party sources ### 8.3 Token Refresh We attempt to automatically refresh OAuth tokens before they expire. However, token refresh may fail due to: - Provider API issues - Revoked farmer authorization - Network connectivity problems You should implement error handling for expired or invalid tokens. --- ## 9. Intellectual Property ### 9.1 Our Intellectual Property We retain all rights to: - The FieldMCP platform, APIs, and documentation - Our trademarks, logos, and branding - Any software, tools, or technology we provide ### 9.2 Your Intellectual Property You retain all rights to: - Applications you build using our Service - Your business logic and proprietary code - Your trademarks and branding ### 9.3 Farmer Data Farmers retain ownership of their agricultural data. Neither you nor we acquire ownership rights to farmer data by virtue of it passing through the Service. ### 9.4 License Grant We grant you a limited, non-exclusive, non-transferable, revocable license to use the Service in accordance with these Terms. This license terminates when your account is terminated. --- ## 10. Third-Party Services ### 10.1 Provider Terms Your use of data from third-party providers (John Deere, etc.) is subject to those providers' terms of service. You are responsible for complying with all applicable provider terms. ### 10.2 Payment Processor We use Stripe for payment processing. Your payment information is handled directly by Stripe according to their privacy policy and terms of service. ### 10.3 Infrastructure We use third-party infrastructure providers for hosting, database, and authentication services. Our use of these providers is governed by our agreements with them. A current list of sub-processors is available upon request. --- ## 11. Limitation of Liability ### 11.1 Disclaimer of Warranties THE SERVICE IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO: - MERCHANTABILITY - FITNESS FOR A PARTICULAR PURPOSE - NON-INFRINGEMENT - ACCURACY OR COMPLETENESS OF DATA ### 11.2 Agricultural Data Accuracy Disclaimer **WE DO NOT WARRANT THE ACCURACY, COMPLETENESS, TIMELINESS, OR RELIABILITY OF ANY AGRICULTURAL DATA ACCESSED THROUGH THE SERVICE.** Specifically, we disclaim liability for: - **Field boundary accuracy**: GeoJSON boundaries may not match legal property lines or actual field edges - **Yield data accuracy**: Historical harvest data may contain sensor errors, calibration issues, or incomplete coverage - **Planting data accuracy**: Seeding rates, dates, and varieties may be incorrectly recorded by equipment - **Equipment information**: Machine status, specifications, and locations may be outdated or inaccurate - **Map layers**: Prescription maps, yield maps, and spatial data may contain errors or gaps You acknowledge that: - Agricultural data originates from third-party equipment and providers - Data may contain errors from sensors, calibration, connectivity, or human input - Decisions based on this data are made at your sole risk - We are not responsible for crop losses, equipment damage, input waste, yield reduction, or business decisions made using data from the Service - You should verify critical data through independent sources before making significant agricultural decisions ### 11.3 Third-Party Service Dependency Disclaimer **THE SERVICE DEPENDS ON THIRD-PARTY APIS AND INFRASTRUCTURE PROVIDERS OUTSIDE OUR CONTROL.** We do not guarantee and are not responsible for: - Availability or uptime of John Deere Operations Center APIs or any other agricultural data provider - Changes to third-party API functionality, endpoints, or data formats - Third-party authentication or OAuth service availability - Data accuracy from agricultural equipment manufacturers - Infrastructure provider (Supabase, Vercel) availability beyond their published SLAs - Stripe payment processing availability When third-party services are unavailable: - API requests will fail or return errors - Token refresh may not complete successfully - Dashboard functionality may be limited - Farmer connections may require re-authentication You should: - Implement error handling for failed API requests in your applications - Cache critical data in your own systems where appropriate - Not rely solely on our Service for time-sensitive or safety-critical operations - Have contingency plans for service unavailability ### 11.4 Token Management Disclaimer We attempt to automatically refresh OAuth tokens before expiration. However, token refresh may fail due to: - Third-party API outages or rate limiting - Farmer revoking authorization through the provider - Network connectivity issues - Token format or protocol changes by the provider - Our infrastructure availability When token refresh fails: - Connections are marked as requiring re-authentication - You are responsible for monitoring connection status - You are responsible for notifying affected users and guiding them through re-authorization - We do not send notifications directly to farmers - Historical access is lost until re-authentication completes ### 11.5 No Agricultural Advice **THE SERVICE DOES NOT PROVIDE AGRICULTURAL ADVICE, RECOMMENDATIONS, OR AGRONOMIC GUIDANCE.** We do not: - Recommend planting dates, varieties, or populations - Advise on fertilizer, pesticide, or herbicide applications - Suggest equipment settings or operational parameters - Provide yield predictions or optimization recommendations - Offer crop insurance, risk management, or financial guidance For agricultural advice, consult qualified agronomists, extension services, or certified crop advisors. ### 11.6 Data Freshness Disclaimer Agricultural data accessed through the Service may not reflect real-time conditions: - **Equipment data**: May be hours or days old depending on connectivity and sync schedules - **Field operations**: Recorded after completion, not during operations - **Boundaries**: Reflect last known configuration, not necessarily current state - **Telemetry**: Subject to equipment connectivity and provider update schedules Do not use this Service for time-critical decisions requiring real-time data or for safety-critical applications. ### 11.7 Limitation of Damages TO THE MAXIMUM EXTENT PERMITTED BY LAW: - Our total liability for any claims arising from the Service shall not exceed the fees paid or payable by you to us in the 12 months immediately preceding the claim - We shall not be liable for any indirect, incidental, special, consequential, or punitive damages - We shall not be liable for lost profits, lost data, business interruption, or other commercial damages - We shall not be liable for crop losses, yield reduction, equipment damage, input waste, or any agricultural losses ### 11.8 Essential Purpose These limitations apply even if any remedy fails of its essential purpose. --- ## 12. Indemnification ### 12.1 Indemnification by You You agree to indemnify, defend, and hold harmless the Company and its officers, directors, employees, and agents from any claims, damages, losses, liabilities, costs, and expenses (including reasonable attorneys' fees) arising from: - Your use of the Service - Your violation of these Terms - Your violation of any third-party rights - Your applications built using the Service - Your content, including farmer data you access through the Service - Claims by farmers or other third parties related to your use of the Service - Any claim that your content or your use of the Service in violation of these Terms infringes, misappropriates, or otherwise violates any third party's intellectual property or other proprietary rights ### 12.2 Indemnification by Us We agree to indemnify, defend, and hold harmless you and your officers, directors, employees, and agents from any claims, damages, losses, liabilities, costs, and expenses (including reasonable attorneys' fees) arising from any claim that the Service, when used by you in accordance with these Terms, infringes, misappropriates, or otherwise violates any third party's intellectual property or other proprietary rights. **Exceptions:** We have no obligation under this section for claims arising from: (a) your modification of the Service; (b) your combination of the Service with materials not provided by us; (c) your use of the Service in violation of these Terms; or (d) third-party data content returned by agricultural data providers (such as John Deere). ### 12.3 Indemnification Procedure The indemnified party must: (a) promptly notify the indemnifying party of the claim; (b) give the indemnifying party sole control of the defense and settlement; and (c) provide reasonable cooperation at the indemnifying party's expense. The indemnified party may participate in the defense at its own expense. The indemnifying party may not settle any claim that admits fault or imposes obligations on the indemnified party without the indemnified party's prior written consent. --- ## 13. Termination ### 13.1 Termination by You You may cancel your account at any time through the dashboard or by contacting us. Cancellation takes effect at the end of your current billing period. No refunds are provided. ### 13.2 Termination by Us We may suspend or terminate your account as follows: We may decline to provide, or may suspend or terminate, the Service to any applicant or account at our sole discretion, including where we determine an applicant or account is a competitor or is using the Service for competitive evaluation, provided we do not act on any basis prohibited by law. **Immediate (no notice required):** - Your use poses a security risk - We are required to do so by law **With 15 days' written notice (curable):** - You violate these Terms (other than security-related violations) - You fail to pay fees when due If you cure the violation within 15 days of notice, your account will be restored. **With 30 days' notice:** - We discontinue the Service ### 13.3 Effect of Termination Upon termination: - Your OAuth tokens and credentials are immediately revoked - Your access to the dashboard is revoked - Your data is deleted according to our retention policy: - OAuth tokens and credentials: Deleted immediately - Account profile, farmer/enterprise connections, usage logs, settings: Deleted at the end of the 30-day recovery window; removed from backups in the normal course of our backup rotation - Billing and payment records: Retained 7 years (federal and state tax record-keeping); payment transaction records are also independently retained by Stripe under Stripe's own retention schedule ### 13.4 Survival The following sections survive termination: Intellectual Property, Limitation of Liability, Indemnification, Dispute Resolution, and any other provisions that by their nature should survive. --- ## 14. Dispute Resolution ### 14.1 Governing Law These Terms are governed by the laws of the State of Missouri, without regard to conflict of law principles. ### 14.2 Informal Resolution Before filing any legal action, you agree to attempt informal resolution by contacting us at legal@fieldmcp.com. We will attempt to resolve the dispute within 30 days. ### 14.3 Binding Arbitration — Developer and Business Users If you use the Service as a developer, business entity, or on behalf of an organization (a "Business User"), and informal resolution fails, any dispute shall be resolved by binding arbitration administered by the American Arbitration Association (AAA) under its **Commercial Arbitration Rules**. The arbitration shall take place in Missouri. Each party shall bear its own filing fees and arbitration costs unless the arbitrator determines otherwise. ### 14.4 Binding Arbitration — Farmers and Individual End Users If you are a farmer or individual whose agricultural data account is connected to the Service (an "End User"), and informal resolution fails, any dispute shall be resolved by binding arbitration administered by the American Arbitration Association (AAA) under its **Consumer Arbitration Rules**. The following consumer protections apply: - **Filing fees**: Your filing fee shall not exceed the amount set by the AAA Consumer Arbitration Rules (currently $225). We will pay all remaining arbitration fees and costs - **Location**: Arbitration hearings will be held in your county of residence, or by telephone or video conference at your election - **Small claims court**: Either party may bring claims in small claims court in Missouri if the claim falls within the court's jurisdictional limit ### 14.5 Class Action Waiver YOU AGREE TO RESOLVE DISPUTES ONLY ON AN INDIVIDUAL BASIS AND WAIVE ANY RIGHT TO PARTICIPATE IN CLASS ACTIONS, CLASS ARBITRATIONS, OR REPRESENTATIVE ACTIONS. ### 14.6 Severability of Dispute Resolution Provisions The enforceability of Section 14.3 (Business Users) is independent of Section 14.4 (End Users), and vice versa. If any provision of this Section 14 is found unenforceable as to one category of user, the remaining provisions continue in full force for all other users. If arbitration is found entirely unenforceable as to any party, disputes with that party shall proceed in the state or federal courts located in Missouri. ### 14.7 Injunctive Relief Notwithstanding the above, either party may seek injunctive relief in any court of competent jurisdiction to prevent irreparable harm. --- ## 15. Changes to Terms ### 15.1 Modifications We may modify these Terms at any time. We will provide notice of material changes by: - Email to your registered address - Prominent notice on the dashboard - At least 30 days before changes take effect ### 15.2 Acceptance If you do not agree to a material change, you may terminate the Service within 30 days of notice with a pro-rata refund for any prepaid, unused fees. Continued use of the Service after the 30-day notice period constitutes acceptance of the modified Terms. --- ## 16. General Provisions ### 16.1 Entire Agreement These Terms, together with our Privacy Policy, Data Processing Agreement, and Service Level Agreement, constitute the entire agreement between you and the Company regarding the Service. ### 16.2 Severability If any provision of these Terms is found unenforceable, the remaining provisions remain in effect. ### 16.3 Waiver Our failure to enforce any right or provision does not constitute a waiver of that right or provision. ### 16.4 Assignment Neither party may assign these Terms without the other party's prior written consent, except in connection with a merger, acquisition, or sale of all or substantially all of its assets, provided the assignee agrees in writing to be bound by these Terms. Any purported assignment in violation of this section is void. ### 16.5 No Agency Nothing in these Terms creates a partnership, agency, or employment relationship. ### 16.6 Force Majeure Neither party is liable for failure or delay in performance due to causes beyond its reasonable control, including natural disasters, acts of government, pandemic, internet or telecommunications failures, third-party API outages, power failures, or cyberattacks. The affected party must provide prompt notice and use reasonable efforts to mitigate the impact. --- ## 17. Contact Information If you have questions about these Terms, please contact us: **FieldMCP LLC** Email: legal@fieldmcp.com Address: 117 SOUTH LEXINGTON ST STE 100 HARRISONVILLE, MO 64701 --- *By using FieldMCP, you acknowledge that you have read, understood, and agree to be bound by these Terms of Service.* ## Data Processing Agreement URL: https://www.fieldmcp.com/legal/dpa # Data Processing Agreement **Effective Date:** September 12, 2026 **Last Updated:** January 10, 2026 --- This Data Processing Agreement ("DPA") forms part of the Terms of Service between FieldMCP LLC ("Processor," "we," "us," or "our") and the entity agreeing to these terms ("Controller," "you," or "your") and governs the processing of personal data in connection with the FieldMCP platform and related services (the "Service"). --- ## 1. Definitions **"Data Protection Laws"** means all applicable laws relating to data protection and privacy, including the California Consumer Privacy Act (CCPA) and other US state privacy laws. **"Personal Data"** means any information relating to an identified or identifiable natural person processed by the Processor on behalf of the Controller in connection with the Service. **"Processing"** means any operation performed on Personal Data, including collection, recording, organization, storage, adaptation, retrieval, consultation, use, disclosure, erasure, or destruction. **"Data Subject"** means the identified or identifiable natural person to whom Personal Data relates, including Farmers whose agricultural data is accessed through the Service. **"Farmer"** means an individual or entity whose agricultural data account is connected to the Service through OAuth authorization. **"Sub-processor"** means any third party engaged by the Processor to process Personal Data on behalf of the Controller. **"Security Incident"** means any accidental or unlawful destruction, loss, alteration, unauthorized disclosure of, or access to Personal Data. **"Service Provider"** has the meaning given in California Civil Code § 1798.140(ag). --- ## 2. Scope and Roles ### 2.1 Roles of the Parties - **Controller**: You determine the purposes and means of processing Farmer Personal Data. You are responsible for obtaining Farmer consent and ensuring lawful basis for processing. - **Processor**: We process Personal Data solely on your behalf and according to your documented instructions as set forth in this DPA and the Service functionality. - **Data Subjects**: Farmers whose agricultural data is accessed through connections you establish. ### 2.2 Subject Matter of Processing The Processor processes Personal Data to provide the Service, which includes: - Storing and managing OAuth tokens for Farmer connections - Routing API requests to agricultural data providers - Refreshing OAuth tokens automatically before expiration - Logging usage data for billing and analytics - Caching authentication and rate limit data ### 2.3 Duration of Processing Processing begins when you create a Farmer connection and continues until: - You delete the Farmer connection, or - Your account is terminated, or - You instruct us to delete the data Post-termination, data is retained according to Section 4.8 of this DPA. ### 2.4 Nature and Purpose of Processing | Processing Activity | Purpose | |---------------------|---------| | Token storage | Enable API authentication with providers | | Token encryption | Protect credentials at rest | | Token refresh | Maintain continuous access | | Request routing | Direct API calls to appropriate providers | | Usage logging | Billing, analytics, debugging | | Caching | Performance optimization, rate limiting | ### 2.5 Types of Personal Data | Data Category | Examples | |---------------|----------| | OAuth credentials | Access tokens, refresh tokens | | Account identifiers | Provider user IDs, organization IDs | | Agricultural data (in transit) | Field names, equipment info, yield data | | Usage metadata | Timestamps, tool names, response times | ### 2.6 Categories of Data Subjects - Farmers who authorize OAuth connections - Farm employees with provider account access - Agricultural business operators --- ## 3. Controller Obligations ### 3.1 Lawful Basis You represent and warrant that: - You have a lawful basis for processing Farmer Personal Data - You have obtained all necessary consents from Farmers before connecting their accounts - You have provided Farmers with adequate privacy notices describing your use of their data - Your use of the Service complies with all applicable Data Protection Laws ### 3.2 Instructions Your instructions for processing are set forth in: - This DPA - The Terms of Service - The Service documentation - API requests you submit through the Service You may provide additional written instructions, provided they are consistent with the Service functionality. ### 3.3 Farmer Communications You are solely responsible for: - Communicating with Farmers about data access and use - Responding to Farmer inquiries about their data - Notifying Farmers when connections require re-authentication - Handling Farmer complaints or concerns --- ## 4. Processor Obligations ### 4.1 Processing Limitations We will: - Process Personal Data only on your documented instructions - Not process Personal Data for our own purposes beyond providing the Service - Not sell Personal Data to third parties - Not share Personal Data for cross-context behavioral advertising To the extent the California Consumer Privacy Act (CCPA) applies, we are a Service Provider. We certify that we understand and will comply with the restrictions in CCPA § 1798.100(d). We will not retain, use, or disclose Personal Data for any purpose other than performing the Service, and will not combine Personal Data with data from other sources except as permitted by the CCPA. ### 4.2 Confidentiality We ensure that personnel authorized to process Personal Data: - Are subject to confidentiality obligations - Process Personal Data only as necessary to provide the Service - Receive appropriate training on data protection ### 4.3 Security Measures We implement and maintain appropriate technical and organizational measures to protect Personal Data, including: **Encryption:** - OAuth tokens encrypted at rest using ChaCha20-Poly1305 authenticated encryption - Encryption keys stored in Supabase Vault (isolated from database) - Automated quarterly key rotation with natural token migration - All data transmitted over HTTPS/TLS 1.2+ **Access Controls:** - Row-level security (RLS) ensuring tenant isolation - OAuth 2.1 authentication with ES256 JWT signing - Rate limiting on authentication endpoints - Automatic lockout after repeated authentication failures **Infrastructure:** - Managed infrastructure with SOC 2 Type II certified providers - Database backups with point-in-time recovery - Automatic cache expiration and cleanup **Monitoring:** - Error logging and alerting - Authentication failure tracking - Usage monitoring for anomaly detection ### 4.4 Sub-processors #### 4.4.1 Authorized Sub-processors You authorize the use of the following Sub-processors: | Sub-processor | Purpose | Location | Data Processed | |---------------|---------|----------|----------------| | Supabase, Inc. | Database, authentication, edge functions | United States | All Personal Data | | John Deere & Company | Agricultural data API provider | United States | OAuth tokens, API requests | | Stripe, Inc. | Payment processing | United States | Controller email, billing data | | Vercel, Inc. | Dashboard hosting | United States | Session data, cookies | #### 4.4.2 Sub-processor Changes We will: - Notify you at least 30 days before adding or replacing Sub-processors - Provide you an opportunity to object to new Sub-processors - If you object, we will make reasonable efforts to provide an alternative arrangement that avoids the objected-to Sub-processor. If no alternative is commercially feasible within 30 days, you may terminate the affected Service with a pro-rata refund for any prepaid, unused fees #### 4.4.3 Sub-processor Obligations We ensure that Sub-processors: - Are bound by data protection obligations no less protective than this DPA - Implement appropriate security measures - Process Personal Data only as necessary to provide their services ### 4.5 Data Subject Rights We will assist you in responding to Data Subject requests to exercise their rights under applicable Data Protection Laws, including requests to: - Access their Personal Data - Correct inaccurate Personal Data - Delete their Personal Data - Restrict processing - Data portability **Response Process:** 1. If we receive a request directly from a Data Subject, we will promptly notify you 2. We will provide reasonable assistance to help you respond within required timeframes 3. Standard assistance (included at no charge) covers: data export via the Service dashboard, deletion of Farmer connections and associated tokens, and written confirmation of deletion. Assistance requiring custom engineering work (e.g., manual database queries, bespoke reports) may be subject to additional fees at our then-current professional services rates, quoted in advance ### 4.6 Security Incident Response #### 4.6.1 Notification If we become aware of a Security Incident affecting Personal Data, we will: - Notify you without undue delay and in any event within 72 hours of confirming that a Security Incident has occurred. The notification timeline begins when we have sufficient information to confirm a Security Incident, not upon initial detection of a potential anomaly - Provide notification to legal@fieldmcp.com or your designated security contact #### 4.6.2 Notification Content Our notification will include, to the extent known: - Description of the nature of the Security Incident - Categories and approximate number of Data Subjects affected - Categories and approximate number of Personal Data records affected - Name and contact details of our data protection contact - Likely consequences of the Security Incident - Measures taken or proposed to address the Security Incident #### 4.6.3 Cooperation We will: - Cooperate with your investigation of the Security Incident - Take reasonable steps to mitigate effects and prevent recurrence - Not notify Data Subjects directly without your prior approval, unless required by law ### 4.7 Audits and Assessments #### 4.7.1 Information Provision Upon your reasonable request (no more than once per year), we will provide: - Documentation of our security measures - Summary of recent security assessments or certifications - Answers to reasonable security questionnaires For all customers, we will make available upon request the most recent SOC 2 Type II report from our primary infrastructure provider (currently Supabase, Inc.), along with a summary of any additional security measures we implement beyond the provider's baseline. #### 4.7.2 On-Site Audits For Enterprise customers with appropriate contractual arrangements: - We will allow audits by you or your designated third-party auditor - Audits require 30 days' advance notice - Audits must be conducted during normal business hours - Audit scope is limited to processing activities covered by this DPA - You bear the costs of audits you initiate ### 4.8 Data Deletion and Return Upon termination of the Service or your written request: **Immediate Deletion:** - OAuth tokens (access and refresh) - OAuth credentials (client IDs, encrypted tokens) - Active cache entries **Retained for Limited Periods:** - Account profile data: 90 days - Usage logs: 90 days (anonymized after 30 days by removing account and Farmer identifiers) - Billing records: 3 years (legal compliance) We will certify deletion upon your request. --- ## 5. Data Transfers ### 5.1 Location of Processing Personal Data is processed in the United States. All Sub-processors process data within the United States. ### 5.2 Geographic Restriction The Service is available only to Controllers established in the United States. By entering into this DPA, you represent that you are not subject to the EU General Data Protection Regulation (GDPR) or the UK Data Protection Act 2018. If your circumstances change such that GDPR or UK data protection law applies, you must notify us immediately, and we will work with you to establish appropriate transfer mechanisms or terminate the affected processing. --- ## 6. Liability ### 6.1 Allocation of Liability Each party's liability under this DPA is subject to the limitations of liability in the Terms of Service. ### 6.2 Controller Liability You are liable for: - Ensuring lawful basis for processing - Obtaining necessary Farmer consents - Accuracy of instructions provided to us - Your applications' compliance with Data Protection Laws ### 6.3 Processor Liability We are liable for: - Processing Personal Data contrary to your documented instructions - Failure to implement agreed security measures - Unauthorized Sub-processor engagement - Security Incidents caused by our negligence --- ## 7. Term and Termination ### 7.1 Term This DPA is effective from the Effective Date and continues for the duration of your use of the Service. ### 7.2 Survival The following obligations survive termination: - Confidentiality (indefinitely) - Data deletion and return (until completed) - Liability provisions - Any obligation that by its nature should survive --- ## 8. General Provisions ### 8.1 Conflicts In the event of a conflict between this DPA and the Terms of Service, this DPA governs with respect to Personal Data processing. ### 8.2 Amendments We may update this DPA to reflect changes required by Data Protection Laws. For material changes not required by law, we will provide 30 days' advance notice. If you do not agree to a material change, you may terminate the Service within 30 days of notice with a pro-rata refund for any prepaid, unused fees. Continued use of the Service after the 30-day notice period constitutes acceptance of the updated DPA. ### 8.3 Governing Law This DPA is governed by the laws of the State of Missouri, without regard to conflict of law principles. Any disputes arising under this DPA are subject to the dispute resolution provisions in the Terms of Service. ### 8.4 Assignment Neither party may assign this DPA without the other party's prior written consent, except in connection with a merger, acquisition, or sale of all or substantially all of its assets, provided the assignee agrees in writing to be bound by this DPA. Any purported assignment in violation of this section is void. --- ## 9. Contact Information For questions about this DPA or to exercise rights under it: **Data Protection Contact:** FieldMCP LLC Email: legal@fieldmcp.com Address: 117 SOUTH LEXINGTON ST STE 100 HARRISONVILLE, MO 64701 --- ## Appendix A: Technical and Organizational Security Measures ### A.1 Encryption | Data | Method | Key Management | |------|--------|----------------| | OAuth tokens at rest | ChaCha20-Poly1305 | Supabase Vault (quarterly rotation) | | Data in transit | TLS 1.2+ | Managed certificates | | JWT signing keys | ES256 (ECDSA P-256) | Supabase Vault | ### A.2 Access Controls | Control | Implementation | |---------|----------------| | Authentication | Email one-time passcode (OTP) via Supabase Auth, optional TOTP MFA | | Authorization | Row-level security policies | | API access | OAuth 2.1 with ES256-signed JWTs | | Rate limiting | Per-minute and monthly limits by tier | | Brute force protection | IP-based lockout after failures | ### A.3 Infrastructure Security | Measure | Provider | |---------|----------| | Database hosting | Supabase (AWS infrastructure) | | Edge functions | Supabase (Deno runtime) | | Dashboard hosting | Vercel | | DDoS protection | Cloudflare (via providers) | | Backups | Automated daily with PITR | ### A.4 Operational Security | Practice | Description | |----------|-------------| | Logging | Request logging with error tracking | | Monitoring | Uptime and error rate monitoring | | Incident response | Documented response procedures | | Access reviews | Periodic review of access permissions | --- *By using the FieldMCP Service, you acknowledge that you have read and agree to this Data Processing Agreement.* ## Service Level Agreement URL: https://www.fieldmcp.com/legal/sla # Service Level Agreement **Effective Date:** September 12, 2026 **Last Updated:** July 13, 2026 --- This Service Level Agreement ("SLA") is part of the Terms of Service between FieldMCP LLC ("Company," "we," "us," or "our") and you ("Customer," "you," or "your") and describes our uptime commitments for the FieldMCP platform. **This SLA applies only to paid subscription tiers. The Free tier has no uptime commitment.** --- ## 1. Definitions **"Downtime"** means periods when the MCP Gateway endpoint (`https://api.fieldmcp.com/mcp`) is unavailable or returns HTTP 5xx errors to properly authenticated requests, excluding Scheduled Maintenance and Exclusions defined in Section 4. **"Monthly Uptime Percentage"** means the total number of minutes in a calendar month minus Downtime minutes, divided by the total number of minutes in that month, expressed as a percentage. **"Service Credit"** means a credit applied to your account as compensation for Downtime exceeding our commitment. **"Scheduled Maintenance"** means planned maintenance announced at least 72 hours in advance via email to your registered address. --- ## 2. Uptime Commitment ### 2.1 Uptime Targets | Subscription Tier | Monthly Uptime Target | |-------------------|----------------------| | Free | No commitment | | Developer | 99.0% | | Startup | 99.5% | | Enterprise | 99.9% (or as negotiated) | ### 2.2 Uptime Calculation ``` Monthly Uptime % = ((Total Minutes - Downtime Minutes) / Total Minutes) x 100 ``` **Example:** In a 30-day month (43,200 minutes), a Developer tier customer experiencing 432 minutes of Downtime would have: - Monthly Uptime = (43,200 - 432) / 43,200 = 99.0% - This meets the 99.0% target; no Service Credit is due. ### 2.3 Measurement Downtime is measured by our monitoring systems. Downtime begins when our systems confirm the Service is returning 5xx errors to valid authenticated requests and ends when normal operation resumes. --- ## 3. Service Credits ### 3.1 Credit Schedule If we fail to meet your tier's uptime commitment, you may request Service Credits: | Monthly Uptime Achieved | Service Credit (% of Monthly Fee) | |-------------------------|-----------------------------------| | 99.0% - 99.49% | 10% | | 95.0% - 98.99% | 25% | | 90.0% - 94.99% | 50% | | Below 90.0% | 100% | ### 3.2 Credit Limitations - **Exclusive Remedy**: Service Credits are your sole and exclusive remedy for any failure to meet the uptime commitments in this SLA. This does not limit your rights under the Terms of Service for matters other than uptime availability - **Maximum Credit**: 100% of your monthly subscription fee for the affected month - **Form**: Credits are applied to future invoices only; no cash refunds - **Expiration**: Unused credits expire 12 months after issuance - **Non-Transferable**: Credits cannot be transferred to other accounts ### 3.3 How to Request Credits To request a Service Credit, email legal@fieldmcp.com within 30 days of the incident with: 1. Your account email address 2. Date(s) and time(s) of the Downtime (UTC) 3. Description of the impact on your application 4. Any error messages or logs you received We will respond within 10 business days with our determination. If we confirm the Downtime, we will apply the appropriate Service Credit to your next invoice. ### 3.4 Disputes If you disagree with our determination, you may request a review by providing additional evidence. We will make a final determination within 15 business days of receiving your dispute. ### 3.5 Chronic Failure Termination If the Monthly Uptime Percentage falls below your tier's commitment for three (3) consecutive months, you may terminate the Service with immediate effect by providing written notice within 30 days of the third consecutive failure. In such case, we will provide a pro-rata refund for any prepaid, unused fees. --- ## 4. Exclusions The following are NOT counted as Downtime and do not qualify for Service Credits: ### 4.1 Third-Party Service Outages Unavailability or errors caused by services outside our control: - **John Deere Operations Center API** unavailability, errors, or degraded performance - **Supabase** infrastructure incidents (when we are also affected) - **Cloudflare** infrastructure incidents (Workers or edge network) - **Stripe** payment processing issues - **Internet backbone** or DNS infrastructure failures - Any other third-party API or service provider outages ### 4.2 Scheduled Maintenance - Maintenance announced at least 72 hours in advance - Individual maintenance windows not exceeding 4 hours - Maximum 8 hours of scheduled maintenance per calendar month - Emergency security patches (announced as soon as practicable) ### 4.3 Force Majeure Events beyond our reasonable control, including: - Natural disasters (earthquakes, floods, hurricanes, etc.) - Acts of war, terrorism, or civil unrest - Government actions or court orders - Pandemics or public health emergencies - Power grid failures affecting data centers ### 4.4 Customer-Caused Issues Issues attributable to your actions or systems: - Invalid or expired OAuth tokens - Authentication failures due to incorrect credentials - Requests exceeding your tier's rate limits (HTTP 429 responses) - Malformed API requests (HTTP 4xx responses) - Your network, infrastructure, or application issues - Farmer connections requiring re-authentication ### 4.5 Abuse and Security - Traffic exceeding 5x your tier's documented rate limits - Distributed denial of service (DDoS) attacks targeting you or us - Security incidents requiring protective measures - Suspension of your account for Terms of Service violations ### 4.6 Beta Features - Features marked as "beta," "preview," or "experimental" - Newly launched features during their first 30 days - Features explicitly excluded from SLA coverage in documentation --- ## 5. What This SLA Does NOT Cover This SLA provides commitments for **Service availability only**. It does not guarantee: ### 5.1 Data Accuracy - Accuracy, completeness, or timeliness of agricultural data from third-party providers - Correctness of field boundaries, yield data, or equipment information - Data quality from John Deere or other connected services ### 5.2 Token Refresh Success - Successful automatic refresh of OAuth tokens - Continuous access to Farmer connections - Token refresh when Farmers revoke authorization or providers are unavailable ### 5.3 Performance - Response time or latency targets - Throughput or request processing speed - Query performance for any specific operation ### 5.4 Dashboard Availability - The web dashboard (`fieldmcp.com`) availability - Dashboard features or functionality - Account management interface uptime ### 5.5 Third-Party API Functionality - Availability of specific John Deere API endpoints - Data returned by agricultural providers - Changes to third-party API functionality or data formats --- ## 6. Support Response Times ### 6.1 Support Tiers | Priority Level | Description | Developer | Startup | Enterprise | |----------------|-------------|-----------|---------|------------| | **Critical** | Service completely unavailable | 8 hours | 4 hours | 1 hour | | **High** | Major feature non-functional | 24 hours | 8 hours | 4 hours | | **Medium** | Feature impaired, workaround exists | 48 hours | 24 hours | 8 hours | | **Low** | General questions, minor issues | 72 hours | 48 hours | 24 hours | ### 6.2 Priority Definitions - **Critical**: Complete Service unavailability affecting production applications - **High**: Major functionality broken with significant business impact - **Medium**: Functionality impaired but workaround available - **Low**: General questions, documentation requests, minor issues ### 6.3 Support Hours - **Developer/Startup**: Business hours (9 AM - 5 PM Central, Monday-Friday) - **Enterprise**: 24/7 for Critical issues; business hours for others ### 6.4 Support Channels - **Email**: legal@fieldmcp.com - **Enterprise**: Dedicated support contact (if applicable) --- ## 7. Maintenance Windows ### 7.1 Scheduled Maintenance We perform routine maintenance to ensure Service reliability. Scheduled maintenance: - Is announced at least 72 hours in advance via email - Typically occurs during low-traffic periods (Sundays 2-6 AM Central) - Does not exceed 4 hours per window - Is limited to 8 hours total per calendar month ### 7.2 Emergency Maintenance We may perform emergency maintenance without advance notice for: - Critical security vulnerabilities - Imminent threat of data loss - Legal or regulatory compliance requirements We will provide notice as soon as practicable and minimize disruption. ### 7.3 Maintenance Notifications Maintenance notifications are sent to the email address associated with your account. Ensure your contact information is current in the dashboard. --- ## 8. Incident Communication ### 8.1 Status Updates During Service disruptions, we will: - Acknowledge the incident within 30 minutes of detection - Provide status updates at least every 60 minutes during ongoing incidents - Send notification when the incident is resolved - Publish a post-incident summary for significant outages ### 8.2 Communication Channels - **Email**: Direct notification to affected customers - **Status Page**: https://status.fieldmcp.com/ - **Dashboard**: Banner notifications for active incidents --- ## 9. Your Responsibilities To benefit from this SLA, you must: ### 9.1 Maintain Valid Credentials - Keep OAuth connections active and properly secured - Monitor and maintain Farmer connections - Re-authenticate connections when required ### 9.2 Implement Error Handling - Handle API errors gracefully in your applications - Implement appropriate retry logic for transient failures - Respect rate limits and back off when receiving 429 responses ### 9.3 Stay Informed - Keep your account email address current - Monitor maintenance notifications - Review status updates during incidents ### 9.4 Report Issues Promptly - Report suspected Downtime within 24 hours - Provide requested diagnostic information - Cooperate with troubleshooting efforts --- ## 10. SLA Modifications ### 10.1 Changes We may modify this SLA with 30 days' advance notice. Changes take effect at the start of your next billing cycle after the notice period. ### 10.2 Notification SLA changes will be communicated via: - Email to your registered address - Dashboard notification - Updated "Last Updated" date on this document ### 10.3 Acceptance If you do not agree to a material change, you may terminate the Service within 30 days of notice with a pro-rata refund for any prepaid, unused fees. Continued use of the Service after the 30-day notice period constitutes acceptance of the modified SLA. --- ## 11. Entire SLA This SLA, together with the Terms of Service, constitutes the complete agreement regarding Service availability. This SLA supersedes any prior availability commitments. This SLA is governed by the laws of the State of Missouri. In the event of a conflict between this SLA and the Terms of Service, the Terms of Service govern except with respect to uptime commitments and Service Credits, which are controlled by this SLA. --- ## 12. Contact Information For SLA-related inquiries, Service Credit requests, or to report Downtime: **FieldMCP LLC** Email: legal@fieldmcp.com Address: 117 SOUTH LEXINGTON ST STE 100 HARRISONVILLE, MO 64701 --- ## Appendix: Uptime History We will maintain a public record of monthly uptime percentages and significant incidents. This appendix will be updated monthly. | Month | Uptime % | Incidents | Notes | |-------|----------|-----------|-------| | *To be populated* | - | - | - | --- *This Service Level Agreement is effective as of the date listed at the top of this document.*