Skip to main content
Glama
fwextensions

DataSF MCP Server

by fwextensions

DataSF MCP Server

A Model Context Protocol (MCP) server that provides LLMs with seamless access to San Francisco's open data portal (DataSF), powered by the Socrata platform.

Overview

This MCP server enables AI assistants like Claude to search, explore, and query San Francisco's public datasets through a simple, standardized interface. It handles the complexity of the Socrata API, provides intelligent column name correction, and includes schema caching for optimal performance.

Key Features

  • πŸ” Dataset Search & Discovery - Find datasets by keywords or browse by category

  • πŸ“Š Schema Retrieval - Get column names and data types before querying

  • πŸ’¬ SoQL Query Execution - Run SQL-like queries against any dataset

  • 🎯 Fuzzy Column Matching - Auto-corrects typos in column names

  • ⚑ Schema Caching - Reduces API calls with intelligent caching

  • πŸ” Optional Authentication - Supports Socrata App Tokens for higher rate limits

  • βœ… Property-Based Testing - Comprehensive correctness guarantees

Related MCP server: CKAN MCP Server

Available Tools

1. search_datasf

Search for datasets by keywords.

Parameters:

  • query (string, required): Search keywords (1-500 characters)

  • limit (number, optional): Max results (default: 5, max: 20)

Example:

Search for police incident datasets

2. list_datasf

Browse available datasets, optionally filtered by category.

Parameters:

  • category (string, optional): Filter by category

  • limit (number, optional): Max results (default: 5, max: 20)

Example:

List recent public safety datasets

3. get_schema

Get the schema (columns and data types) for a specific dataset.

Parameters:

  • dataset_id (string, required): Dataset 4x4 ID (format: xxxx-xxxx)

Example:

Get the schema for dataset wg3w-h783

4. query_datasf

Execute a SoQL (Socrata Query Language) query against a dataset.

Parameters:

  • dataset_id (string, required): Dataset 4x4 ID

  • soql (string, required): SoQL query (1-4000 characters)

  • auto_correct (boolean, optional): Enable column name correction (default: true)

Example:

Query dataset wg3w-h783: SELECT incident_category, COUNT(*) GROUP BY incident_category LIMIT 10

Installation

Prerequisites

  • Node.js 18 or higher

  • npm or yarn

Local Setup (Optional)

If you want to run or modify the server locally:

  1. Clone the repository:

git clone https://github.com/fwextensions/datasf-mcp.git
cd datasf-mcp
  1. Install dependencies:

npm install
  1. Run the server:

npm start

The server uses tsx to run TypeScript directly without a build step.

Usage

Testing with MCP Inspector

For the MCP Inspector, you'll need to use the local installation:

# First, clone and install locally
git clone https://github.com/fwextensions/datasf-mcp.git
cd datasf-mcp
npm install

# Then run the inspector
npx -y @modelcontextprotocol/inspector tsx src/index.ts

In the inspector UI, use:

  • Command: tsx

  • Arguments: src/index.ts (or absolute path if running from outside the directory)

The easiest way to use the server is directly from GitHub using npx:

{
  "mcpServers": {
    "datasf": {
      "command": "npx",
      "args": ["-y", "github:fwextensions/datasf-mcp"],
      "env": {
        "SOCRATA_APP_TOKEN": "your-optional-token"
      }
    }
  }
}

This will automatically download and run the latest version from GitHub without any manual installation.

Local Installation

Alternatively, clone and install locally:

git clone https://github.com/fwextensions/datasf-mcp.git
cd datasf-mcp
npm install

Then use the absolute path in your MCP configuration (see below).

Configuration for Claude Desktop

Add to your Claude Desktop config file:

Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json

Option 1: Using npx (recommended)

{
  "mcpServers": {
    "datasf": {
      "command": "npx",
      "args": ["-y", "github:fwextensions/datasf-mcp"],
      "env": {
        "SOCRATA_APP_TOKEN": "your-optional-token"
      }
    }
  }
}

Option 2: Using local installation

{
  "mcpServers": {
    "datasf": {
      "command": "npx",
      "args": ["tsx", "/absolute/path/to/datasf-mcp/src/index.ts"],
      "env": {
        "SOCRATA_APP_TOKEN": "your-optional-token"
      }
    }
  }
}

Important: Replace /absolute/path/to/datasf-mcp with the actual full path to where you cloned this project.

Configuration for Kiro IDE

Create or edit .kiro/settings/mcp.json:

Option 1: Using npx from GitHub (recommended)

{
  "mcpServers": {
    "datasf": {
      "command": "npx",
      "args": ["-y", "github:fwextensions/datasf-mcp"],
      "env": {
        "SOCRATA_APP_TOKEN": "your-optional-token"
      },
      "disabled": false,
      "autoApprove": []
    }
  }
}

Option 2: Using local installation

{
  "mcpServers": {
    "datasf": {
      "command": "npx",
      "args": ["tsx", "src/index.ts"],
      "env": {
        "SOCRATA_APP_TOKEN": "your-optional-token"
      },
      "disabled": false,
      "autoApprove": []
    }
  }
}

Getting a Socrata App Token

The server works without authentication for public data, but an App Token increases rate limits:

  1. Visit https://data.sfgov.org/

  2. Sign up for a free account

  3. Navigate to Developer Settings

  4. Create a new App Token

  5. Add it to your MCP configuration

Development

Project Structure

datasf-mcp-server/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts              # MCP server entry point
β”‚   β”œβ”€β”€ socrataClient.ts      # Socrata API client
β”‚   β”œβ”€β”€ validator.ts          # Input validation with Zod
β”‚   β”œβ”€β”€ fuzzyMatcher.ts       # Column name auto-correction
β”‚   β”œβ”€β”€ cache.ts              # Schema caching
β”‚   β”œβ”€β”€ errorHandler.ts       # Error handling utilities
β”‚   └── __tests__/
β”‚       └── property/         # Property-based tests
β”œβ”€β”€ dist/                     # Compiled JavaScript output
β”œβ”€β”€ package.json
└── tsconfig.json

Available Scripts

  • npm run build - Compile TypeScript to JavaScript

  • npm start - Run the compiled server

  • npm test - Run all tests

  • npm run test:watch - Run tests in watch mode

Running Tests

npm test

The project uses property-based testing with fast-check to ensure correctness across a wide range of inputs.

Architecture

The server follows a modular architecture:

  1. MCP Server - Handles protocol communication via stdio

  2. Socrata Client - Manages HTTP requests to Socrata APIs

  3. Validator - Validates all inputs using Zod schemas

  4. Fuzzy Matcher - Corrects column name typos using Fuse.js

  5. Schema Cache - Caches dataset schemas in memory (5-minute TTL)

  6. Error Handler - Classifies and formats errors for LLM consumption

Example Queries

Once configured in your LLM, you can ask questions like:

  • "Search for datasets about housing in San Francisco"

  • "What's the schema for the police incidents dataset (wg3w-h783)?"

  • "Show me the top 10 incident categories from the police incidents dataset"

  • "Find all building permits issued in 2024"

  • "What datasets are available about transportation?"

API Endpoints Used

The server interacts with three Socrata APIs:

  • Discovery API: https://api.us.socrata.com/api/catalog/v1 - Dataset search and browsing

  • Views API: https://data.sfgov.org/api/views/{id}.json - Schema retrieval

  • Resource API: https://data.sfgov.org/resource/{id}.json - Data querying

Error Handling

The server provides descriptive error messages for:

  • Validation errors - Invalid input format or length

  • Not found - Dataset doesn't exist

  • Rate limiting - Too many requests (add App Token to resolve)

  • Timeouts - Request exceeded 30 seconds

  • API errors - Socrata-specific errors (e.g., SoQL syntax errors)

Contributing

Contributions are welcome! The project uses:

  • TypeScript for type safety

  • Zod for runtime validation

  • fast-check for property-based testing

  • Vitest as the test runner

License

MIT

Resources

Troubleshooting

Server not starting

  • Ensure you ran npm run build first

  • Check that Node.js 18+ is installed

Tools not showing up in LLM

  • Verify the path in your config is absolute

  • Restart your LLM application after adding the config

  • Check the LLM's logs for connection errors

Rate limiting errors

  • Add a Socrata App Token to your configuration

  • Reduce the frequency of requests

Column name errors in queries

  • Use get_schema first to see valid column names

  • Enable auto_correct: true (default) for automatic typo correction

Available Tools

4 tools
get_schemaA

Get the schema (columns and data types) for a specific dataset. Call this before writing queries to learn the correct field names.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataset_idYesDataset 4x4 ID (format: xxxx-xxxx)

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It describes the tool's purpose and usage context but lacks details on permissions, rate limits, error handling, or response format. The description doesn't contradict any annotations, but it misses key behavioral traits for a tool that likely involves data access.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose and followed by a practical usage guideline. Every sentence adds value without redundancy, making it efficiently structured and appropriately sized for a simple tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (one parameter, no nested objects) and high schema coverage, the description is mostly complete for its purpose. However, with no output schema and no annotations, it could benefit from mentioning the response format or any constraints, slightly limiting completeness for an agent invoking the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with the input schema fully documenting the dataset_id parameter's type, format, and pattern. The description adds no additional parameter semantics beyond what the schema provides, such as examples or edge cases, so it meets the baseline score of 3 for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Get the schema') and resource ('for a specific dataset'), with the explicit purpose of learning field names before writing queries. It distinguishes from siblings like list_datasf, query_datasf, and search_datasf by focusing on metadata retrieval rather than data listing, querying, or searching.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool ('Call this before writing queries to learn the correct field names'), providing clear context for its application. It implies an alternative workflow where users might skip this step and risk errors, though it doesn't name specific sibling alternatives for schema-related tasks.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_datasfB

Browse available datasets from San Francisco's open data portal. Optionally filter by category. Returns recently updated or popular datasets.

ParametersJSON Schema
NameRequiredDescriptionDefault
categoryNoOptional category filter
limitNoMaximum number of results (default: 5, max: 20)

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions that it returns 'recently updated or popular datasets,' which adds some context about the return behavior, but it lacks details on permissions, rate limits, pagination, or error handling. For a tool with zero annotation coverage, this is a significant gap in transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded, consisting of two sentences that efficiently convey the tool's purpose and key features. There's no wasted text, and it avoids redundancy, though it could be slightly more structured by explicitly separating purpose from behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (2 parameters, no output schema, no annotations), the description is adequate but incomplete. It covers the basic purpose and some behavioral traits, but it lacks details on output format, error handling, and sibling tool differentiation, which would enhance completeness for effective agent use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, so the schema already documents both parameters (category and limit) with descriptions and constraints. The description adds marginal value by mentioning 'optionally filter by category,' which aligns with the schema but doesn't provide additional syntax or format details beyond what's in the structured fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Browse available datasets from San Francisco's open data portal' specifies the verb (browse) and resource (datasets). It distinguishes from siblings by mentioning filtering by category and returning recently updated/popular datasets, though it doesn't explicitly name alternatives like search_datasf.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context through 'optionally filter by category' and 'returns recently updated or popular datasets,' suggesting it's for general browsing rather than specific searches. However, it doesn't explicitly state when to use this tool versus siblings like search_datasf or query_datasf, nor does it provide exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_datasfA

Execute a SoQL (Socrata Query Language) query against a dataset. Supports auto-correction of column names. Returns query results as JSON.

ParametersJSON Schema
NameRequiredDescriptionDefault
dataset_idYesDataset 4x4 ID (format: xxxx-xxxx)
soqlYesSoQL query string (1-4000 characters)
auto_correctNoEnable automatic column name correction (default: true)

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses key behavioral traits: execution of SoQL queries, support for auto-correction, and JSON return format. However, it lacks details on error handling, rate limits, authentication needs, or side effects, which are important for a query tool with no structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that efficiently conveys purpose, key feature (auto-correction), and output format (JSON). It is front-loaded with the main action and avoids unnecessary details, making it highly concise and effective.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations and no output schema, the description is moderately complete. It covers the tool's purpose and basic behavior but lacks details on error responses, pagination, or result structure, which would be helpful for an AI agent to use the tool effectively in complex scenarios.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description adds marginal value by mentioning auto-correction in context, but does not provide additional semantic details beyond what the schema specifies (e.g., examples of SoQL queries or auto-correction behavior).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Execute' with the resource 'a SoQL query against a dataset', specifies the language (SoQL), and mentions auto-correction and JSON return format. It distinguishes from siblings like get_schema (metadata) and list_datasf/search_datasf (likely list/search operations) by focusing on query execution.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for querying datasets with SoQL, but does not explicitly state when to use this tool versus alternatives like search_datasf or list_datasf. It mentions auto-correction as a feature, which provides some context, but lacks explicit guidance on scenarios or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_datasfC

Search for public datasets in San Francisco's open data portal by keywords. Returns dataset IDs, names, and descriptions.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesSearch keywords (1-500 characters)
limitNoMaximum number of results (default: 5, max: 20)

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions that it 'Returns dataset IDs, names, and descriptions,' which gives some output context, but lacks details about permissions (though implied as public), rate limits, error handling, or pagination. For a search tool with zero annotation coverage, this leaves significant behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded in a single sentence, efficiently stating the tool's purpose and return values. Every word earns its place, with no redundant information. It could be slightly improved by structuring usage guidance, but it's well-sized for its content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (search with two parameters), no annotations, and no output schema, the description is minimally adequate. It covers the basic purpose and return format but lacks details on behavioral traits, sibling differentiation, and error cases. It meets the minimum viable threshold but has clear gaps in context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents both parameters ('query' and 'limit'). The description adds no additional parameter semantics beyond what's in the schemaβ€”it doesn't explain search syntax, result ordering, or how 'limit' interacts with defaults. Baseline 3 is appropriate when the schema handles parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Search for public datasets in San Francisco's open data portal by keywords.' It specifies the verb ('Search'), resource ('public datasets'), and scope ('San Francisco's open data portal'). However, it doesn't explicitly differentiate from sibling tools like 'list_datasf' or 'query_datasf', which prevents a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With sibling tools like 'list_datasf' and 'query_datasf' available, there's no indication of when this search function is appropriate versus listing or querying datasets. The description only states what it does, not when to choose it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A3.8/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: get_schema retrieves metadata for a dataset, list_datasf browses datasets with filters, query_datasf executes queries, and search_datasf searches by keywords. There is no overlap in functionality, making tool selection straightforward for an agent.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with 'datasf' as a common suffix (e.g., get_schema, list_datasf, query_datasf, search_datasf). This predictability enhances readability and usability across the tool set.

Tool Count5/5

With 4 tools, the server is well-scoped for its purpose of interacting with San Francisco's open data portal. Each tool serves a distinct and necessary function, covering browsing, searching, querying, and schema retrieval without being overly sparse or bloated.

Completeness5/5

The tool set provides complete coverage for the domain of data exploration and querying: list_datasf and search_datasf enable dataset discovery, get_schema provides metadata for query preparation, and query_datasf allows data retrieval. There are no obvious gaps in the workflow.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides access to San Francisco public permitting, business, and property data through the Socrata SODA API. Users can search permit details, aggregate statistics, and look up property assessments using natural language.
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI assistants to search, explore, and query any CKAN open data portal through natural language, making public datasets accessible without requiring knowledge of the portal's API.
    20
    414
    57
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to query and retrieve San Francisco open data from data.sfgov.org via the Socrata SODA API.
    9
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/fwextensions/datasf-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server