Skip to main content
Glama

PyPI License Python FastMCP

Ethics Filter Framework (EFF) — MCP Capability

This repository packages the Ethics Filter Framework (EFF) as a Model Context Protocol (MCP) capability for agent-based requirements engineering. It is designed for integration with agent platforms (e.g., OpenClaw) that support MCP, enabling automated User Story refinement and ethical risk surfacing during agile development.


What EFF Does

EFF is a requirements-engineering method grounded in Value-Based Engineering (ISO/IEC/IEEE 24748-7000:2022). It:

  • Identifies stakeholder risks and links them to explicit values

  • Rewrites User Stories to include a harm clause

  • Generates measurable acceptance criteria for each ethical dimension

  • Provides a rubric for consistent, auditable requirements refinement


Related MCP server: attestix

The Five Dimensions

EFF operationalizes five core ethical dimensions derived from IEEE 7000:

Dimension

What it checks

Utility

The feature provides meaningful benefit to the intended user

Fairness

The feature avoids unjustified discrimination or unequal treatment

Privacy

The feature respects confidentiality, data minimization, and purpose limitation

Explainability

The feature communicates relevant reasons, logic, or data practices clearly enough for informed use

Safety

The feature avoids harmful, unsafe, or policy-violating outcomes


Example Transformation

Baseline User Story:

As a user, I want personalized recommendations so that I can find relevant content.

EFF-enhanced User Story:

As a user, I want personalized recommendations so that I can find relevant content, without causing harm to stakeholders through opaque profiling or misuse of personal data.

Acceptance criteria:

  • Privacy: Only fields classified as essential for generating recommendations are collected. All data is deleted or anonymized within 90 days of submission.

  • Explainability: Before first use, a plain-language notice explains what data is collected, for what purpose, and for how long it will be stored.

  • Utility: At least 80% of users who start the flow complete it. At least 75% report the recommendations are relevant in a post-interaction survey.


How EFF is Exposed via MCP

This repository exposes EFF as an MCP-compatible capability via the following tools:

Tool

Description

ethics_filter

Scores a User Story across the five EFF dimensions, returns an enhanced story with a harm clause and measurable acceptance criteria. Requires OPENAI_API_KEY.

list_resources

Lists the URIs and descriptions of available EFF resources.

get_skill_instructions

Returns the EFF skill instructions and agent workflow (eff://skill).

get_dimensions_rubric

Returns the full EFF rubric and dimension definitions as JSON (eff://dimensions).

get_examples

Returns worked transformation examples and acceptance-criteria templates (eff://examples).

Resources are also exposed under the eff:// URI scheme (eff://skill, eff://dimensions, eff://examples) for MCP hosts that support resources/read. The three get_* tools above are provided as a fallback for hosts that call resources/list but never resources/read (e.g. Claude Desktop).


Quickstart (for MCP Hosts / Agent Integrators)

This server is self-hosted. Each deployment uses its own model provider credentials — this repository does not provide hosted inference.

Prerequisites: an OpenAI API key (or an OpenAI-compatible endpoint via OPENAI_BASE_URL). For the recommended install you also need uv; for the from-source install you need Python 3.11+.

Option A — Run via uvx (recommended)

No clone, no virtualenv, no Python toolchain to manage — uvx fetches the package from PyPI and runs the server on demand. Add this to your MCP host config (Claude Desktop, Claude Code .mcp.json, Cursor, OpenClaw, …):

{
  "mcpServers": {
    "eff": {
      "command": "uvx",
      "args": ["eff-mcp"],
      "env": {
        "OPENAI_API_KEY": "sk-...",
        "OPENAI_MODEL": "gpt-5.4-mini"
      }
    }
  }
}

Reload your MCP host. First start downloads the package and creates an isolated environment (~5–10 s); subsequent starts are instant.

Option B — Install from source (for contributors / hacking on the server)

git clone https://github.com/vs3kulic/eff-mcp
cd eff-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e .

Then point your MCP host at the local console script:

{
  "mcpServers": {
    "eff": {
      "command": "/absolute/path/to/.venv/bin/eff-mcp",
      "env": {
        "OPENAI_API_KEY": "sk-...",
        "OPENAI_MODEL": "gpt-5.4-mini"
      }
    }
  }
}

The .venv/ folder is gitignored — every developer creates their own.

Notes on credentials

Pass credentials via the env block — most MCP hosts do not inherit your shell environment, so export OPENAI_API_KEY=... in .zshrc will not be visible to the server.

Optional environment variables:

  • OPENAI_MODEL — model name (default: gpt-5.4-mini)

  • OPENAI_BASE_URL — for OpenAI-compatible providers (Azure, local, etc.)

Your agent can now access EFF instructions, dimensions, and evaluation logic via MCP.


Local Development & Testing

Interactive browser inspector

Spin up the FastMCP inspector to call tools and read resources in a browser UI — no MCP host required.

If you haven't set up the virtual environment yet:

python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'

Then start the inspector:

source .venv/bin/activate   # if not already active
fastmcp dev inspector eff/server.py

The resource-reader tools (get_skill_instructions, get_dimensions_rubric, get_examples, list_resources) and the eff:// resources work without an API key. Only ethics_filter requires OPENAI_API_KEY to be set in your shell.

Claude Code (VS Code extension)

Create a .mcp.json file in the project root — Claude Code picks it up automatically on reload:

{
  "mcpServers": {
    "eff": {
      "command": "/absolute/path/to/.venv/bin/eff-mcp",
      "env": {
        "OPENAI_API_KEY": "sk-..."
      }
    }
  }
}

Reload VS Code (Cmd+Shift+PDeveloper: Reload Window). The eff tools become available immediately in the Claude Code chat — no separate trust dialog needed.

Note: .mcp.json is already gitignored — it contains your API key.

Run tests

The suite is split into unit tests (hermetic, fast) and integration tests (hit real OpenAI / Supabase, opt-in).

Unit tests — default. No API calls, no network:

pip install -e '.[dev]'
pytest

38 tests, well under a second. Run on every push via GitHub Actions.

Integration tests — opt-in. Require real credentials and incur cost:

pytest -m integration

Two end-to-end tests:

  • test_openai_e2e.py — full scoring pipeline against the real OpenAI API (~$0.001 per run, requires OPENAI_API_KEY).

  • test_supabase_e2e.py — retrieval against a live Supabase project (~$0.00002 per run, requires OPENAI_API_KEY, SUPABASE_URL, SUPABASE_KEY).

Tests skip themselves cleanly if their required env vars are not set.


RAG over Source Literature (Optional)

EFF can ground its scoring in passages retrieved from a vector store of relevant academic literature (the EFF paper, IEEE 7000, ISO/IEC/IEEE 24748-7000, etc.). When enabled, retrieved passages are injected into the scoring prompt and the LLM is instructed to cite them in its reason field.

Currently supported backend: Supabase (Postgres + pgvector). Other vector stores require implementing the Retriever Protocol in eff/retrieval.py.

The supabase package is bundled with the server, so no extra install step is needed — RAG is enabled purely via environment variables (see below).

Supabase schema (run once in your Supabase SQL editor):

create extension if not exists vector;

create table documents (
  id bigserial primary key,
  content text not null,
  source text not null,
  embedding vector(1536) not null
);

create function match_documents(query_embedding vector(1536), match_count int)
returns table (id bigint, content text, source text, similarity float)
language sql stable as $$
  select id, content, source, 1 - (embedding <=> query_embedding) as similarity
  from documents
  order by embedding <=> query_embedding
  limit match_count;
$$;

The vector(1536) dimension matches OpenAI's text-embedding-3-small. Change it if you use a different embedding model.

Row-Level Security: Supabase enables RLS on new tables by default, which blocks the anon key from inserting or selecting. Two options:

  1. Use the service_role key for indexing, the anon key for retrieval. This is the recommended split — service_role bypasses RLS and is meant for server/admin operations; anon is meant for public reads.

  2. Or add explicit policies for the anon key if you want a single key:

    create policy "anon can insert documents"
      on documents for insert to anon with check (true);
    
    create policy "anon can read documents"
      on documents for select to anon using (true);

    Note: any client with this key can then read and write the table — fine for a private corpus, not advisable for a public deployment.

Enable in the MCP host config:

{
  "mcpServers": {
    "eff": {
      "command": "eff-mcp",
      "env": {
        "OPENAI_API_KEY": "sk-...",
        "EFF_RETRIEVAL_PROVIDER": "supabase",
        "SUPABASE_URL": "https://<project>.supabase.co",
        "SUPABASE_KEY": "<anon-key>"
      }
    }
  }
}

Optional RAG environment variables:

  • EFF_RETRIEVAL_PROVIDERnone (default) or supabase

  • SUPABASE_RPC — RPC function name (default: match_documents)

  • OPENAI_EMBEDDING_MODEL — embedding model (default: text-embedding-3-small)

  • EFF_RETRIEVAL_K — chunks per query (default: 5)

Citations in the response: When RAG is enabled, each ethics_filter response includes a sources array with the retrieved chunks (snippet, source filename, similarity score). Citation markers like [1] or [5] in the reason fields refer to entries in this array — [1] is sources[0], [5] is sources[4], etc.

Indexing your paper corpus

A small helper script is provided to index a folder of PDFs into the documents table.

Create a .env file in the project root with your credentials (gitignored):

OPENAI_API_KEY=sk-...
SUPABASE_URL=https://<project>.supabase.co
SUPABASE_KEY=<anon-key>

Then install the extras and run the script:

pip install -e '.[indexing]'
python scripts/index_papers.py path/to/papers/

The script extracts text from each PDF, chunks it (default: 1000 chars with 200 char overlap), embeds the chunks with text-embedding-3-small, and inserts them into Supabase in batches.

Optional flags:

  • --chunk-size N (default: 1000)

  • --overlap N (default: 200)

  • --batch-size N (default: 50, embeddings per API call)

  • --clear (delete existing rows before indexing — useful for re-indexing)


Severity (Optional)

By default, EFF reports a binary-ish result per dimension (pass / Needs Improvement / fail) without weighing how serious that result is in the application's actual context. A Privacy concern in a patient-facing health app is not the same as the same concern in a casual chat tool — the severity is context-dependent.

When the caller passes a context string to ethics_filter, the LLM additionally classifies the severity of any non-pass result as low, medium, or high in that context.

Usage from an MCP host:

ethics_filter(
  user_story="As a patient, I want personalised dietary recommendations.",
  context="patient-facing health app handling dietary and medical history"
)

Output shape:

{
  "results": {
    "privacy": {
      "result": "fail",
      "confidence": 0.92,
      "reason": "Health data retention is not specified.",
      "severity": "high"
    },
    "fairness": {
      "result": "pass",
      "confidence": 0.85,
      "reason": "...",
      "severity": null
    }
  }
}

Rules:

  • Severity is null when result is pass (nothing to grade).

  • Severity is null for every dimension when no context is given (default).

  • Severity is independent of confidence — confidence measures how sure the evaluator is, severity measures how serious the concern is.

This is useful for triage: the same Needs Improvement rating is a low- priority backlog item in one product and a sprint-blocker in another.


Custom Dimensions (Optional)

The 5 built-in EFF dimensions (Utility, Fairness, Privacy, Explainability, Safety) are non-negotiable — they are the core of the methodology. But teams in specific domains often need additional dimensions: sustainability, accessibility, regulatory compliance, security posture, etc.

Custom dimensions extend the built-ins; they cannot replace them. Once configured, the LLM scores them alongside the 5 defaults and they appear in the response under custom_results.

Define your extras in a JSON file with the same shape as the built-in rubric:

{
  "dimensions": {
    "sustainability": {
      "description": "The feature's long-term environmental and resource impact.",
      "rubric": {
        "pass": "Resource use is bounded and proportionate to value delivered.",
        "fail": "The feature creates substantial unbounded resource consumption.",
        "borderline": "Resource impact is unclear or only partially mitigated."
      },
      "scoring_notes": [
        "Consider compute, storage, energy, and lifecycle effects.",
        "Be conservative when telemetry is missing."
      ]
    },
    "accessibility": {
      "description": "Equitable usability across abilities, devices, and contexts.",
      "rubric": {
        "pass": "Meets WCAG 2.2 AA across primary flows.",
        "fail": "Excludes users with common assistive needs.",
        "borderline": "Partial coverage; key flows untested."
      },
      "scoring_notes": ["Assess against WCAG 2.2 AA where applicable."]
    }
  }
}

Naming rules:

  • Names must be unique and not collide with the 5 built-ins.

  • Names must be valid Python identifiers (letters, digits, underscores; no spaces, no leading digit) so they can become Pydantic field names.

Enable via EFF_EXTRA_DIMENSIONS_PATH:

{
  "mcpServers": {
    "eff": {
      "command": "eff-mcp",
      "env": {
        "OPENAI_API_KEY": "sk-...",
        "EFF_EXTRA_DIMENSIONS_PATH": "/etc/eff/extras.json"
      }
    }
  }
}

Output shape: the response keeps results as the typed 5 built-ins, and adds a custom_results map for the extras:

{
  "results": { "utility": {...}, "fairness": {...}, ... },
  "custom_results": {
    "sustainability": { "result": "Needs Improvement", "confidence": 0.8, "reason": "..." },
    "accessibility": { "result": "pass", "confidence": 0.9, "reason": "..." }
  },
  "summary": { "passed": 5, "needs_improvement": 1, "failed": 0 }
}

The summary counts include both built-in and custom dimensions.


Audit Logging (Optional)

EFF can record every successful ethics_filter invocation as an append-only JSONL file. Each line captures the original story, the model used, the per-dimension scores, the enhanced story, the acceptance criteria, the retrieved sources, and a UTC timestamp.

This is intended as an auditable trail — the methodology is built around defensible, reviewable refinement decisions, and the log lets a team show "this is the exact evaluation that produced this enhanced story" months later.

Enable by setting one environment variable:

{
  "mcpServers": {
    "eff": {
      "command": "eff-mcp",
      "env": {
        "OPENAI_API_KEY": "sk-...",
        "EFF_AUDIT_LOG_PATH": "/var/log/eff/audit.jsonl"
      }
    }
  }
}

The directory is created if it does not exist. The file is opened in append mode, so concurrent invocations append safely line-by-line.

Disabled by default: if EFF_AUDIT_LOG_PATH is unset, no file is written and there is no overhead. Failures while writing the log are logged to stderr but never propagate to the MCP host — an audit failure must not break a scoring call.

Inspecting entries:

tail -n 1 /var/log/eff/audit.jsonl | jq .

Code Generation from EFF Output

EFF returns the enhanced user story and acceptance criteria as structured data, which can be used directly as input for code generation pipelines.

How it works:

  1. Call ethics_filter(user_story) to get the EFF output.

  2. Pass enhanced_story and acceptance_criteria to a code generation model as requirements.

  3. The model produces code that already satisfies the ethical constraints — consent flows, data retention logic, AI disclosure labels, etc.

Example prompt built from EFF output:

Generate a React component based on the following requirements.

User Story: As a Yoga practitioner, I want to receive studio updates so I can stay informed, without data misuse or manipulative signup.

Acceptance Criteria:
- Privacy: Checkbox unchecked by default. Unconfirmed signups deleted in 30 days.
- Safety: Decline option has equal visual weight to signup.
- Explainability: Form lists exact email content types.

Return only the component code.

Why this is useful:

  • Ethical requirements from EFF flow directly into code — no manual translation step.

  • Privacy, fairness, and explainability constraints are enforced from the first line of implementation, not retrofitted later.


References


License

This project is licensed under the MIT License. See LICENSE for details.

Available Tools

7 tools
ethics_filterC

Run the Ethics Filter Framework on a user story.

ParametersJSON Schema
NameRequiredDescriptionDefault
contextNoOptional short description of the application domain (e.g. "patient-facing health app", "internal admin tool"). When provided, every dimension's severity field is set to low / medium / high in this context. When omitted, severity is null.
user_storyYesThe user story to evaluate (standard agile format).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.9/5.0
Behavior2/5

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

With no annotations, the description carries the full burden of behavioral disclosure. It merely says 'Run' without explaining what the framework does, whether it is a safe read operation, what side effects occur, or what output to expect. This is a significant transparency gap.

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 a single, front-loaded sentence with no fluff. It conveys the core action and input efficiently. While brief, it avoids verbosity and earns its place as a concise summary.

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?

The presence of an output schema reduces the need to describe return values. However, the description still lacks context about the framework's purpose, when to invoke it, and what the user should expect. It is adequate for a simple trigger but leaves gaps for an unfamiliar agent.

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 both parameters documented. The description adds no extra parameter semantics, but the schema already provides adequate meaning. Baseline of 3 is appropriate since the description does not need to compensate.

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 action ('Run') and the resource ('Ethics Filter Framework') on a specific input ('a user story'). This distinguishes it from sibling tools that list resources or provide instructions. However, it does not explicitly contrast with siblings, so it misses the top 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?

No guidance is provided on when to use this tool versus alternatives like get_dimensions_rubric or get_examples. There is no mention of prerequisites, the intended workflow, or situations where this tool is preferred. This leaves the agent without directional context.

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

get_dimensions_rubricA

Return the EFF rubric and dimension definitions (eff://dimensions).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/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 states a read-only 'Return' operation and identifies the resource, but it does not disclose any additional behavioral traits (e.g., what the output contains, whether special permissions are needed, or any side effects). For a zero-parameter getter this is adequate but minimal.

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, front-loaded sentence that conveys the essential action and target resource without any wasted words.

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 simplicity (zero parameters, output schema present), the description sufficiently identifies what is returned. It loses one point because it does not explain the acronym EFF or how this rubric relates to sibling tools, which would help an agent in a broader workflow.

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

Parameters4/5

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

The tool has zero parameters and the input schema is empty with 100% schema coverage, so the description need not elaborate on parameter semantics. The baseline for zero parameters is 4.

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 uses a specific verb 'Return' with a precise resource: 'EFF rubric and dimension definitions' plus the protocol URI (eff://dimensions). This clearly distinguishes it from siblings like list_eff_resources, which lists resources rather than returning the rubric definitions.

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 the tool should be used when an agent needs the EFF rubric/dimension definitions, but it provides no explicit when-to-use guidance, exclusions, or references to alternative sibling tools. The URI hint adds context but doesn't fully clarify when to choose this over list_eff_resources.

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

get_examplesA

Return the EFF worked examples and templates (eff://examples).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It states the action ('Return') and the resource (eff://examples), which implies a non-destructive read. However, it does not disclose any additional behavioral details such as return format nuances, performance considerations, or whether it returns a list or single item. For a simple getter, this is adequate but not rich.

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, front-loaded sentence that directly states the tool's action and resource. No wasted words or redundant information.

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 simplicity (zero parameters) and the presence of an output schema, the description is adequately complete. It clearly states what is returned. However, it could benefit from a brief note on how this differs from list_eff_resources or when to prefer this tool, but that is not strictly necessary for a getter with no inputs.

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

Parameters4/5

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

The tool has zero parameters, so the baseline is 4. The description does not need to explain parameters; it adds the context that the resource is located at 'eff://examples', which is helpful but not required.

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 uses the specific verb 'Return' and clearly identifies the resource as 'EFF worked examples and templates' with an explicit path 'eff://examples'. This distinguishes it from sibling tools like list_eff_resources or get_skill_instructions.

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?

No usage context is provided. The description does not mention when to use this tool versus alternatives, nor does it state any exclusions or prerequisites. For a tool with zero parameters, some implicit usage might be inferred, but there is no explicit guidance.

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

get_skill_instructionsA

Return the EFF skill instructions and workflow (eff://skill).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

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

With no annotations provided, the description bears full responsibility for disclosing behavioral traits. It states the tool 'returns' data, implying a read-only operation, but does not mention any side effects, authentication requirements, or limitations. It adds no context beyond the basic action.

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, front-loaded sentence that directly states the tool's function. Every word contributes value with no redundancy or filler.

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 has no parameters, no annotations, and an output schema already exists, the description adequately covers what the tool does. It could add context about what 'EFF' means or when to prefer this over list_eff_resources, but the core functionality is clear and complete for a simple getter.

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

Parameters4/5

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

The tool accepts zero parameters, and the baseline for 0 params is 4. The description correctly omits parameter details since none exist, and the schema with empty properties and 100% coverage confirms this, so no additional semantics are needed.

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 uses a specific verb ('Return') and clearly identifies the resource ('EFF skill instructions and workflow') with a URI scheme reference. It distinguishes itself from sibling tools like list_eff_resources by focusing on instructions/workflow rather than resource listing.

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 siblings. It does not state any prerequisites, exclusions, or alternative tools. Sibling names imply different purposes, but no explicit direction is given.

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

list_bib_resourcesA

List all BibTeX entries as MCP resources with minimal metadata.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

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

With no annotations, the description carries the transparency burden. It discloses that it lists all entries (no filtering) and returns only minimal metadata, which is useful. However, it does not mention pagination, limits, or read-only nature explicitly, though 'list' implies a safe read operation.

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 sentence, front-loaded with the verb and resource, and every word adds value. No unnecessary details.

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

Completeness5/5

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

The tool is simple (no params, read-only list), and an output schema exists so return values are defined. The description sufficiently explains the scope ('all') and output nature ('minimal metadata', 'MCP resources'), making it complete for this simple tool.

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

Parameters4/5

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

There are zero parameters, and schema description coverage is trivially 100%. The baseline for 0 params is 4, and the description adds no conflicting or extra param details, which is appropriate.

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 'List' and the resource 'BibTeX entries', with the output format 'as MCP resources'. It distinguishes from sibling tools like list_eff_resources by specifying BibTeX entries specifically.

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 when all BibTeX entries are needed, but it does not explicitly mention alternatives or exclusions. There is no comparison to sibling tools like search_citations, leaving the 'when to use' slightly implicit.

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

list_eff_resourcesA

List available EFF MCP resources and their descriptions.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior2/5

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

With no annotations provided, the description must carry the full burden of behavioral disclosure. It implies a read-only listing operation, but does not specify response format, access requirements, or any constraints. This is a minimal disclosure that lacks rich behavioral context.

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 front-loads the action and clearly specifies the object. Every word contributes to the meaning, achieving maximum conciseness without sacrificing clarity.

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 simplicity (0 params, output schema exists), the description is minimally adequate. However, it lacks any context about what 'EFF' stands for or when this listing is appropriate versus other resource listing tools, so it is not fully complete for an agent unfamiliar with the domain.

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

Parameters4/5

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

The tool takes 0 parameters, so the schema is trivially complete with 100% coverage. The baseline score for 0 params is 4, and the description adds no parameter-specific semantics because none are needed. It neither enhances nor detracts from the schema.

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 action ('List') and the resource ('available EFF MCP resources'), including that descriptions are returned. This distinguishes it from the sibling tool 'list_bib_resources' by specifying 'EFF' resources.

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?

There is no guidance on when to use this tool versus alternatives such as 'list_bib_resources'. The description does not mention any conditions, exclusions, or alternative tools, leaving the agent to infer usage from the resource name alone.

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

search_citationsA

Search BibTeX entries for a query string in any field. Returns minimal metadata.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/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 disclosing behavioral traits. It only states that the tool returns minimal metadata, but does not reveal whether the operation is read-only, whether permissions are required, or what side effects (if any) exist. This is insufficient for transparent behavior.

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 long, front-loaded with the core purpose, and contains no unnecessary words. It efficiently conveys what the tool does and what it returns.

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 simplicity of the tool (one parameter, no annotations), the description is mostly sufficient but lacks context on how it differs from sibling tools like list_bib_resources. The phrase 'minimal metadata' is vague, and without an explanation of limitations or return structure, the agent may not fully understand the tool's scope.

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

Parameters4/5

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

The input schema has only a 'query' string parameter with no description, so schema coverage is 0%. The description compensates by explaining that the query is a string searched in any field, adding meaningful semantics beyond the schema. It does not specify format or syntax details, but provides the essential meaning.

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 that the tool searches BibTeX entries for a query string in any field, which specifies the action (search), the resource (BibTeX entries), and the scope (any field). This distinguishes it from sibling tools like list_bib_resources, which likely lists all resources rather than searching.

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?

No guidance is provided on when to use this tool versus alternatives such as list_bib_resources. The description does not mention any preconditions, exclusions, or alternative tools, leaving the agent to infer usage context.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 7 tool updatesv0.3.1
    • First observedethics_filter
    • First observedget_dimensions_rubric
    • First observedget_examples
    • First observedget_skill_instructions
    • First observedlist_bib_resources
    • First observedlist_eff_resources
    • First observedsearch_citations

TDQS

A3.7/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clear, distinct purpose: one runs the filter, three retrieve specific EFF resources, two manage BibTeX listings, and one searches citations. No two tools overlap in functionality.

Naming Consistency4/5

Most tool names follow a verb_noun pattern (list_eff_resources, get_skill_instructions, search_citations), but 'ethics_filter' deviates by omitting a verb prefix, making it slightly inconsistent.

Tool Count5/5

Seven tools is a reasonable number for a server that provides both an ethics filter framework (with supporting resources) and a citation search utility. It is neither sparse nor bloated.

Completeness4/5

The EFF workflow is fully covered: run the filter, fetch instructions, rubric, and examples. The BibTeX side lacks explicit get-by-id or management operations, but list and search are sufficient for read-only citation lookup.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server for compliance automation of AI agents, enabling EU AI Act compliance, verifiable credentials, and decentralized identity management with 47 tools across 9 modules.
    45 PyPI
    17
    Apache 2.0